修补模拟 class 的方法
Patch a method of a mocked class
我的代码结构如下:
我有一个 class MyClass
继承自 BaseClass
(这是一个附带的问题,不是我问题的根源)。然后我有另一个 class MyClassManager
调用 MyClass
.
的方法
我正在为 MyClassManager
的方法编写单元测试,我想控制 MyClass
方法之一的 return 值,同时自动指定其余方法。
在我的测试中,我通过用 autospec=True
修补 class 为 MyClass
创建了一个 Mock。然后我尝试修补方法 MyClass.method_to_patch
并将其替换为 Substitute.substitute_method
。到目前为止,还不错。
但是现在当我 运行 测试时,class 管理器创建了一个 MyClass
的实例,它是一个完全自动指定的 Mock,但它没有修补我想要的方法替代。
有没有办法结合这两个 patch
装饰器来实现我想要的?
class Substitute:
def substitute_method(self, arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)
class BaseClass:
def method_to_patch(self, arg1, arg2):
return arg1 == arg2
class MyClass(BaseClass):
def myclass_method(self):
print("myclass method called")
class MyClassManager:
def method_to_test(self):
my_class = MyClass()
my_class.myclass_method()
my_class.method_to_patch(10, 100)
class TestMyClass(unittest.TestCase):
@patch.object(MyClass, "method_to_patch", Substitute.substitute_method)
@patch("__main__.MyClass", autospec=True)
def test_method_to_test(self, mock_class):
class_manager = MyClassManager()
class_manager.method_to_test()
print(mock_class.call_count)
if __name__ == "__main__":
unittest.main()
要将 class 中的方法模拟为 return 特定值,请使用 @patch。目的。使用@patch 模拟class 中的方法。对象,但每次调用时 return 都是不同的值,请使用 side_effect.
我在以下页面中找到了答案的线索,其中讨论了模拟嵌套属性调用:https://www.integralist.co.uk/posts/mocking-in-python/。相同的逻辑适用于方法调用。
手动调整模拟对象是不够的 - 您必须调整模拟对象的 return_value
。
测试应该是这样的:
class TestMyClass(unittest.TestCase):
@patch("__main__.MyClass", autospec=True)
def test_method_to_test(self, mock_class):
mock_class.return_value.method_to_patch = Substitute.substitute_method
class_manager = MyClassManager()
class_manager.method_to_test()
print(mock_class.call_count)
现在我有一个模拟对象来代替 MyClass
,所以 MyClass.myclass_method
也被模拟了,但我可以根据需要用 Substitute.substitute_method
代替 MyClass.method_to_patch
。
最后一点 - substitute_method
实际上是一个 staticmethod
所以它应该是这样的:
class Substitute:
@staticmethod
def substitute_method(arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)
我的代码结构如下:
我有一个 class MyClass
继承自 BaseClass
(这是一个附带的问题,不是我问题的根源)。然后我有另一个 class MyClassManager
调用 MyClass
.
我正在为 MyClassManager
的方法编写单元测试,我想控制 MyClass
方法之一的 return 值,同时自动指定其余方法。
在我的测试中,我通过用 autospec=True
修补 class 为 MyClass
创建了一个 Mock。然后我尝试修补方法 MyClass.method_to_patch
并将其替换为 Substitute.substitute_method
。到目前为止,还不错。
但是现在当我 运行 测试时,class 管理器创建了一个 MyClass
的实例,它是一个完全自动指定的 Mock,但它没有修补我想要的方法替代。
有没有办法结合这两个 patch
装饰器来实现我想要的?
class Substitute:
def substitute_method(self, arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)
class BaseClass:
def method_to_patch(self, arg1, arg2):
return arg1 == arg2
class MyClass(BaseClass):
def myclass_method(self):
print("myclass method called")
class MyClassManager:
def method_to_test(self):
my_class = MyClass()
my_class.myclass_method()
my_class.method_to_patch(10, 100)
class TestMyClass(unittest.TestCase):
@patch.object(MyClass, "method_to_patch", Substitute.substitute_method)
@patch("__main__.MyClass", autospec=True)
def test_method_to_test(self, mock_class):
class_manager = MyClassManager()
class_manager.method_to_test()
print(mock_class.call_count)
if __name__ == "__main__":
unittest.main()
要将 class 中的方法模拟为 return 特定值,请使用 @patch。目的。使用@patch 模拟class 中的方法。对象,但每次调用时 return 都是不同的值,请使用 side_effect.
我在以下页面中找到了答案的线索,其中讨论了模拟嵌套属性调用:https://www.integralist.co.uk/posts/mocking-in-python/。相同的逻辑适用于方法调用。
手动调整模拟对象是不够的 - 您必须调整模拟对象的 return_value
。
测试应该是这样的:
class TestMyClass(unittest.TestCase):
@patch("__main__.MyClass", autospec=True)
def test_method_to_test(self, mock_class):
mock_class.return_value.method_to_patch = Substitute.substitute_method
class_manager = MyClassManager()
class_manager.method_to_test()
print(mock_class.call_count)
现在我有一个模拟对象来代替 MyClass
,所以 MyClass.myclass_method
也被模拟了,但我可以根据需要用 Substitute.substitute_method
代替 MyClass.method_to_patch
。
最后一点 - substitute_method
实际上是一个 staticmethod
所以它应该是这样的:
class Substitute:
@staticmethod
def substitute_method(arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)