我想修补一个方法,以测试它是否被调用,但同时我不想失去功能,所以我的想法是用自己来修补这个方法:
import unittest
from unittest.mock import Mock, patch
class MyClass():
def foo(self, num):
return num + 2
class myTestClass(unittest.TestCase):
@patch.object(MyClass,'foo', Mock(wraps=MyClass.foo))
def test_foo(self):
my_class = MyClass()
result = my_class.foo(2)
my_class.foo.assert_called_once_with(2)
self.assertEqual(result, 4)
在执行过程中,我得到以下错误:
File "/usr/lib64/python3.6/unittest/mock.py", line 1014, in _mock_call
return self._mock_wraps(*args, **kwargs)
TypeError: foo() missing 1 required positional argument: 'num'
用这种方式打补丁可能吗?可能有一种变通方法
我在这里看到了几个问题:
- 您正在修补类,而不是对象;但是测试对象,而不是类
- 你在用Mock包装,我觉得这是不对的
- 还有一个次要的问题:您将要测试的对象命名为
my_class
,这很容易被误读
我认为您的算法的正确解决方案可以是:
import unittest
from unittest.mock import Mock, patch
class MyClass():
def foo(self, num):
return num + 2
class myTestClass(unittest.TestCase):
@patch.object(MyClass,'foo', wraps=MyClass.foo)
def test_foo(self, mocked):
obj = MyClass()
result = MyClass.foo(obj, 2)
MyClass.foo.assert_called_once_with(obj, 2)
self.assertEqual(result, 4)
if __name__ == '__main__':
unittest.main()
注意:
wraps=MyClass.foo
而不是wraps=Mock(...)
def test_do(self, mocked)
而不是def test_do(self)
(将模拟对象传递给方法(MyClass.foo(obj, 2)
,因为您已经修补了类,而不是对象MyClass.foo.assert_called_once_with(obj, 2)
,因为您必须检查类方法(已修补(
或者,您可以像本测试中那样修补对象:
def test_foo_object(self):
obj = MyClass()
with patch.object(obj, 'foo', wraps=obj.foo):
result = obj.foo(2)
obj.foo.assert_called_once_with(2)
self.assertEqual(result, 4)