python - 修补模拟类的方法
问题描述
我的代码具有以下结构:
我有一个MyClass
继承自的类BaseClass
(这是一个偶然的点,而不是我的问题的根源)。然后我有另一个类MyClassManager
调用MyClass
.
我正在为一种方法编写单元测试,MyClassManager
并且我想控制其中一种方法的返回值,MyClass
同时自动指定其余方法。
在我的测试中,我MyClass
通过使用autospec=True
. 然后我尝试修补该方法MyClass.method_to_patch
并将其替换为Substitute.substitute_method
. 到现在为止还挺好。
但是现在当我运行测试时,类管理器会创建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()
解决方案
我在以下页面中找到了答案的线索,它讨论了模拟嵌套属性调用: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
实际上是 astaticmethod
所以它应该是这样的:
class Substitute:
@staticmethod
def substitute_method(arg1, arg2):
print("Running substitute method")
return (arg1 > 0 and arg2 > 0)
推荐阅读
- javascript - 我的响应式 UI 在引导程序中没有响应
- python - pygraphviz中不同形状的节点
- html - 背景全屏 100vh 但如果屏幕垂直最小化则更大
- android-recyclerview - 如何修复 NullPointerException?
- r - 根据范围条件选择列并包含 NA 值
- python - 在python中自动传递一个变量
- javascript - 使 Textarea 足够适合 maxLangth 属性
- php - 具有多个步骤和验证的 PHP 表单
- javascript - Vue Socket.io-Extended this.$socket.$subscribe is not a function" 切换路由器页面后
- node.js - 节点中原子性的 redis 事务的替代方案