Reputation: 3497
I would like to patch a method to able to test whether it was called or not, but in the same time I dont want to loose the functionality so the idea was to patch the method with itself:
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)
During execution I am getting the following error:
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'
Is this kind of patching possible in this way? There is probably a workaround described here
Upvotes: 2
Views: 4342
Reputation: 109
I see several problems here:
my_class
, which can be misread easily.I think that a right solution for your algorithm can be:
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()
Note that:
wraps=MyClass.foo
instead of wraps=Mock(...)
.def test_do(self, mocked)
instead of def test_do(self)
(mock object is passed to the method).MyClass.foo(obj, 2)
since you have been patched the class, not the object.MyClass.foo.assert_called_once_with(obj, 2)
since you must check the class method (which you have been patched).Alternatively, you can patch the object like in this test:
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)
Upvotes: 1