gpt4 book ai didi

python - 模拟类实例而不调用 `__init__`并模拟它们各自的属性

转载 作者:行者123 更新时间:2023-12-03 08:41:48 25 4
gpt4 key购买 nike

我有一个带有复杂 __init__ 函数的类 MyClass

这个类有一个方法my_method(self),我想测试它。

my_method 仅需要类实例中的属性 my_attribute

有没有一种方法可以模拟类实例而不调用 __init__ 并通过设置每个类实例的属性来代替?

我有:

# my_class.py

from utils import do_something

class MyClass(object):

def __init__(self, *args, **kwargs):
# complicated function which I would like to bypass when initiating a mocked instance class
pass

def my_method(self):
return do_something(self.my_attribute)

我尝试了什么

@mock.patch("my_class.MyClass")
def test_my_method(class_mock, attribute):

instance = class_mock.return_value
instance.my_attribute = attribute

example_instance = my_class.MyClass()

out_my_method = example_instance.my_method()
# then perform some assertions on `out_my_method`

但是,这仍然使用 __init__ 我希望我们可以绕过或模拟。

最佳答案

正如我在评论中提到的,无需创建实例即可测试单个方法的一种方法是:

MyClass.my_method(any_object_with_my_attribute)

这个问题,就像 quamrana's answer 中的两个选项一样,是我们现在已经扩大了任何 future 变化的范围仅仅因为测试。如果对 my_method 的更改需要访问附加属性,我们现在必须更改实现其他内容(SuperClassMockMyClass,或者在本例中为any_object_with_my_attribute_and_another_one)。


让我们举一个更具体的例子:

import json


class MyClass:

def __init__(self, filename):
with open(filename) as f:
data = json.load(f)
self.foo = data.foo
self.bar = data.bar
self.baz = data.baz

def my_method(self):
return self.foo ** 2

此处任何需要 MyClass 实例的测试。由于 __init__ 中的文件访问而很痛苦。更具可测试性的实现会将数据访问方式和有效实例初始化的细节分开:

class MyClass:

def __init__(self, foo, bar, baz):
self.foo = foo
self.bar = bar
self.baz = baz

def my_method(self):
return self.foo ** 2

@classmethod
def from_json(cls, filename):
with open(filename) as f:
data = json.load(f)
return cls(data.foo, data.bar, data.baz)

您必须将 MyClass("path/to/file") 重构为 MyClass.from_json("path/to/file"),但无论您已经 < em>拥有您可以使用的数据(例如在您的测试中) MyClass(1, 2, 3) 创建实例,不需要文件(您只需要在 from_json 本身的测试中考虑该文件)。这使得实例实际需要更加清晰,并且允许引入其他方式来构造实例而不改变接口(interface)。

关于python - 模拟类实例而不调用 `__init__`并模拟它们各自的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62549961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com