In the previous tutorial we used unittest.mock to mock out our test subject’s dependencies, this simplified our tests and allowed us to focus on one piece of functionality at a time. Unfortunately the approach detailed previously has a drawback! Let’s make a change to our test from the previous session and see if we can make the problem appear;
When we run our test, we get the following output;
MagicMock name='read_file' id='75232624'
Whoops indeed! Our mock from the previous test is interfering with subsequent tests and while sometimes this might be the intended behaviour, for example you might want the same behaviour throughout your test case, for the sake of our example let’s say that this isn’t what we expected. So how do we solve it?
Instead of using MagicMock we can use mock.patch;
When using mock.patch the scope of the mock is limited to that with statement, as soon as you exit it the mocked target will go back to normal, in the example above the output is as follows;
<function read_file at 0x038C65B0>
Much better! We also have access to the mock outside the with statement so we can call the same assertions on it;
You can also use mock.patch as a decorator;
Here the mock is the scope of just that test. Personally I’d say the decorator comes looks neater, especially when you have multiple mocks, but that’s just a preference thing.
So that’s how to use mock.patch, but before I conclude this post there’s a couple of important things to consider.
- You may have noticed in the decorator example, the mock is a parameter to the test function. As you add more mocks remember decorators are passed in, in the order that they are read (bottom up). So if I were to add another mock.patch above the existing one, it would be passed in as the argument to the right of the existing one.
- My colleague found this very important article about some of the dangers of mocks, and how your mock could actually be providing false positives. Definitely worth a read!
Thanks again for reading, in future we’re going to delve in to mocking file operations, throwing exceptions and touch on some of the theory of writing good unit tests.