Patching the class is almost certainly not what you want to do here. For example, if you changed your test method to this:
class TestMyClass(unittest.TestCase):
@mock.patch('__main__.MyClass')
def test_add_two(self, dummy_mock):
m_my_class = MyClass(5)
print m_my_class
You will find that rather than getting what you expect:
<__main__.MyClass object at 0x0000000002C53E48>
You'll get this:
<MagicMock name='MyClass()' id='46477888'>
Patching the class in the method means that any time within the method that something tries to instantiate the class it will instead get a mock object. In your particular case, calling MyClass(5)
will return the same mock object as calling dummy_mock
would. This allows you to set up the mock object so that when you go to test your code the mock object will behave as you want it to.
You really would only use this for dependencies, not the class you are testing. So for example, if your class retrieved data from SQL, you'd patch the SQL class to give your class a mock instead of the normal SQL connection. This allows you to test a class in isolation, without having to worry about externals (like the SQL) getting in the way.
In your example though, you seem to be trying to test a method in isolation. A way you could do that is to extract the function from the method and use that. In code:
def test_add_two(self):
test_mock = mock.Mock()
test_mock.add_two = MyClass.add_two.__func__
test_mock.a = 10
result = test_mock.add_two(test_mock)
self.assert_equal(result, 12)
Normally you wouldn't have to pass in an argument for the self
argument, but as here we've pulled out the function you do need to pass in the self
argument. If you want you can turn the function into a method bound to your mock object, like this:
import types
...
test_mock.add_two = types.MethodType(MyClass.add_two.__func__, test_mock, test_mock.__class__)
result = test_mock.add_two()
If the function you are testing calls any other methods, you'll need to either do this or mock it out for each of the methods.
I would advise against using this strategy too much, in part because of needing to take care of methods that the tested method calls. Of course, being able to mock out the methods it depends on may be exactly what you're trying to do. In any case, it requires the unit tests to have a pretty deep understanding of how the method works, and not just of what it is supposed to produce. That makes the test very fragile, making it so that you are likely to see the test break far more often than the method you are testing.