Python Mock and MagicMock

Ryan Ermita
Feb 4 · 3 min read

While I’m looking for a way to test my function that has a pymysql query, I stumble upon a code snippet with this line. (the same time I saw python autospeccing).

I always use Mock when I do unit test in python, and its my first time to see a MagicMock. So it got me curious, what is the difference between the two and when to use one over the other.

Mock and MagicMock

Mock is use for replacing or mocking an object in python unittest while MagicMock is a subclass of Mock with all the magic methods pre-created and ready to use. These are the pre-created magic methods and its default values for MagicMock.

Below is an example of Mock trying to use one of the magic method pre-created in MagicMock.

Below is an example of MagicMock trying to use one of its pre-created magic method.

And below is an example on how can we create those magic methods in Mock manually.

Application

If MagicMock already creates the magic methods automatically, what is the use of Mock? Why not just upgrade the Mock class with pre-created magic methods? and what scenarios can I use Mock and MagicMock? Luckily, someone already ask that question on stackoverflow and it is a pretty good answer. The answer is quoted from Michael Foord the author of Mock.

Q: Why was MagicMock made a separate thing rather than just folding the ability into the default mock object?

A: One reasonable answer is that the way MagicMock works is that it preconfigures all these protocol methods by creating new Mocks and setting them, so if every new mock created a bunch of new mocks and set those as protocol methods and then all of those protocol methods created a bunch more mocks and set them on their protocol methods, you’ve got infinite recursion…

What if you want accessing your mock as a container object to be an error — you don’t want that to work? If every mock has automatically got every protocol method, then it becomes much more difficult to do that. And also, MagicMock does some of this preconfiguring for you, setting return values that might not be appropriate, so I thought it would be better to have this convenience one that has everything preconfigured and available for you, but you can also take a ordinary mock object and just configure the magic methods you want to exist…

The simple answer is: just use MagicMock everywhere if that’s the behavior you want.

Resources

Ryan's Dev Notes

work journal | aha-moments | tech stuff

Ryan Ermita

Written by

Human | Software Engineer

Ryan's Dev Notes

work journal | aha-moments | tech stuff