Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在@patch decorator创建的对象上模拟方法?_Python_Unit Testing_Mocking_Pytest - Fatal编程技术网

Python 如何在@patch decorator创建的对象上模拟方法?

Python 如何在@patch decorator创建的对象上模拟方法?,python,unit-testing,mocking,pytest,Python,Unit Testing,Mocking,Pytest,我试图使用@patch装饰器和模拟对象来测试我的代码使用一些库的行为。不幸的是,我看不到任何方法来做我试图做的事情,只使用装饰器,似乎我应该能够做到。我意识到,一般来说,我应该更关心方法的返回值,而不是它对库的特定调用序列,但是编写一个测试来比较一个图像与另一个图像是非常困难的 我想也许我可以创建我的模拟对象的实例,然后使用@patch.object(…),但这不起作用,显然@patch('MockObject.method')只会模拟类方法。我可以使用和patch.object(someMoc

我试图使用
@patch
装饰器和模拟对象来测试我的代码使用一些库的行为。不幸的是,我看不到任何方法来做我试图做的事情,只使用装饰器,似乎我应该能够做到。我意识到,一般来说,我应该更关心方法的返回值,而不是它对库的特定调用序列,但是编写一个测试来比较一个图像与另一个图像是非常困难的

我想也许我可以创建我的模拟对象的实例,然后使用
@patch.object(…)
,但这不起作用,显然
@patch('MockObject.method')
只会模拟类方法。我可以使用
和patch.object(someMock.return_value,'method')作为mockName来运行代码,但这会使我的测试变得混乱

从some.module导入SomeClass
类对象:
def方法(自我):
通过
类TestClass:
@补丁('SomeClass.open',返回值=MockObject())
@补丁('???.method')#我在这里找不到任何有效的值
根据需要进行def测试(自测试、模拟方法、模拟打开):
instance=SomeClass.open()
instance.method()
mockOpen.assert_调用_once()
mockMethod.assert_调用了_once()
@补丁('SomeClass.open',返回值=MockObject())
def测试混乱(自我,模拟打开):
使用patch.object(mockOpen.return_值'method')作为mockMethod:
instance=SomeClass.open()
instance.method()
mockOpen.assert_调用_once()
mockMethod.assert_调用了_once()

我认为你把事情复杂化了:

import unittest.mock

@unittest.mock.patch.object(SomeClass, open=mock.Mock())
def test_as_desired(self, mock_open):
    instance = SomeClass.open()  # SomeClass.open is a mock, so its return value is too
    instance.method()

    mock_ppen.assert_called_once()
    instance.method.assert_called_once()

修补用于修改创建超出您控制范围的对象;
MockObject
的实例并非如此。我之所以要修补
MockObject.method
是为了验证是否确实调用了该方法(并且使用了我期望的参数,为了简单起见,我在本例中省略了这些参数),所以在实例化它时对其进行配置;不要试图在事后修补它。我将它实例化为另一个
@patch
的返回值。同样,我想修补模拟对象上的方法的原因是,我可以将它注入到测试函数中,并确保它被正确调用。我感谢您的评论和建议。不过,我这么做是有原因的,这很有道理。不幸的是,您的示例代码在pytest中不起作用,因为@patch.object调用似乎无法理解kwargs的使用方式。我替换了
@patch.object(SomeClass'open',return\u value=Mock())
,但是断言
instance.method.assert\u调用了一次()
失败了。实际上,我说的不太正确:一旦我更正了
@patch
调用,我就可以断言
Mock\u open.return\u value.method.assert\u调用了一次