Cameron Maske

How To Mock Patch A Function [Video]

August 23, 2018

Getting started testing with mock can be intimidating and confusing! To combat this, I’ve put together a short video to help you learn the essentials and avoid the common gotchas that can trip you up.

You can run this code live in your browser.
Hit the ▶️ button below to run the tests. Open the files (📄) to see test_dnd.pny and dnd.py.

Transcript

[0:00] Let's get rid of the randomness in this test by mocking it out. Let's start off by importing mock that has been built into Python since version 3.3. If you are Python 2, however, you'll need to install it as a separate package.

[0:14] Next, let's point mock to the function we want to override or patch. In this case our random integer function. Let's set it to always return a value of 5.

[0:23] And let's tell mock to autospec that function. And we'll see why that's important in a bit. And let's include an argument in our test function to grab that mock object. Let's run the test.... and it passes.

[0:37] So there can be a few common gotchas that can trip you up when mocking. When specifiying the path to what you wanna patch you need to take care to point it is being used, but not where it's defined. Let's see that in action and point to the random module or where it is defined.

[0:50] And we can see that our tests failed because it's not being mocked anymore. Speccing makes sure that anything mock tries to mimic it's original a bit more closely. We can see that in action by turning off autospecc'ing and let's add some nonsense to the argument in our random integer function.

[1:11] And now when we run our tests they pass and that's because an unspecced mock will literally take anything you throw at it. Which isn't too useful when your testing. But with autospeccing on, our mocked function will check the right number of arguments.

[1:25] But we can do one better, we can make sure that our mocked function is explicitly called the arguments that we would expect. To do so we can use assert_called_once_with which is a method included on a mock object.

[1:36] Let's run the test to verify... And it passes.


Written by Cameron Maske.
Are you a Python Developer? I'm working on a course about testing with Python with pytest and if you have a spare 5 minutes, I would love to hear about your experiences.
Want to get in touch? Feel free to drop me an email or over on twitter.