from unittest.mock import patch
return 'HAHAHA A'
a = A()
with patch('__main__.A') as a_mock:
a_mock.b.return_value = 'not working'
You replaced the whole class with your patch, not the method on the existing class.
a = A() created an instance of
A before you replaced the class, so
a.__class__ still references the actual class, not the mock.
Mocking can only ever replace one reference at a time, and not the object referenced. Before the patch, both the names
A and the attribute
a.__class__ are references to the class object. You then patched only the
A reference, leaving
a.__class__ in place.
In other words,
a.__class__ is not patched, only
A().b() would print
You'd have to patch just the method on the class, so that
a.__class__ still references
a.b will resolve to the patched
with patch('__main__.A.b') as b_mock: b_mock.return_value = 'working as long as you patch the right object' print(a.b())
>>> with patch('__main__.A.b') as b_mock: ... b_mock.return_value = 'working as long as you patch the right object' ... print(a.b()) ... working as long as you patch the right object
You can't, unfortunately, patch the
a.__class__ reference with a
Mock; Python only lets you use actual classes for that attribute.
>>> with patch('__main__.a.__class__') as a_class_mock: ... a_class_mock.b.return_value = 'working as long as you patch the right object' ... print(a.b()) ... Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.5/unittest/mock.py", line 1312, in __enter__ setattr(self.target, self.attribute, new_attr) TypeError: __class__ must be set to a class, not 'MagicMock' object