I want test that a function has called the __copy__
method (with a given set of arguments) on an object that was passed to it.
Since a DB connection is required to create the object, I thought I should mock it and pass the mock to the function for the test.
However, it seems that __copy__
is returning a mock (not sure if Mock or MagicMock) instance that does not allow arbitrary methods to be called on it. Since my code is calling methods on the new object, it returns the error below.
How can I assert that the __copy__
method was called and still have the rest of the function run without error?
FWIW, I tried assigning old_obj.__class__.return_value = MagicMock()
but it seems it's not returning what I assign to it (i.e. I also assigned ... = 'foo'
but it still returned a mock object).
Example:
class MyClass:
def __init__(self, my_name):
self.my_name = my_name
def speak(self):
print('My name is ' + self.my_name)
def my_func(old_obj, new_name):
new_obj = old_obj.__class__(new_name)
new_obj.speak()
def test_my_func():
old_obj = MagicMock()
old_obj.my_name = 'foo'
my_func(old_obj, 'bar')
Error produced by py.test:
self = <MagicMock spec='str' id='4490339552'>, name = 'speak'
def __getattr__(self, name):
if name in {'_mock_methods', '_mock_unsafe'}:
raise AttributeError(name)
elif self._mock_methods is not None:
if name not in self._mock_methods or name in _all_magics:
> raise AttributeError("Mock object has no attribute %r" % name)
E AttributeError: Mock object has no attribute 'speak'