【发布时间】:2021-08-10 20:47:06
【问题描述】:
我想通过模拟实例的属性来进行测试,但我没有事先访问该实例。没有它我如何模拟属性?这是我的最小可重现代码。
# test.py
class Foo:
def __init__(self, x):
self.x = x
def bar():
return Foo(1).x + 1
def test_bar(mocker):
mocker.patch('test.Foo.x', 2)
assert bar() == 3
$ pytest test.py
FAILED test.py::test_bar - AttributeError: <class 'test.Foo'> does not have the attribute 'x'
这是有道理的,因为Foo 类没有x,只有实例。如果我添加一个 kwarg mocker.patch('test.Foo.x', 2, create=True) 我就会得到这个
$ pytest test.py
FAILED test.py::test_bar - assert 2 == 3
因为Foo.x 将被模拟,但当实例稍后设置self.x = x 时会被覆盖。
【问题讨论】:
-
测试没有意义。函数
bar()创建一个Foo(1)。为什么要测试创建Foo(2)的情况?如果传递给Foo()的参数可以更改,那么这将提供一个测试发生情况的机会。但它不能。也许你应该断言Foo(var).x == var代替。 -
@Mark 这是一段更长更复杂代码的示例。我同意,如果我正在测试这段代码,我不会尝试模拟它。
-
如果这个实例没有在函数中创建,那么也许你可以传入一个mock。如果它是在实例中创建的,那么也许您可以模拟导致它以某种方式创建的条件。一般来说,您应该针对接口进行测试,而不是内部实现。如果您需要模拟内部结构,则测试的困难可能在于建议对代码进行重构。
-
感谢您的cmets
标签: python mocking pytest pytest-mock