According to the documentation, MagicMock is a subclass of Mock with default implementations of most of the magic methods.

Let’s say we have a function dosomething whose argument is an instance of class A. That class A has an attribute which is an instance of class B, and B has an attribute containing a list of objects of class C. So the function looks something like this:

def dosomething(objA):
    alist = objA.objB.some_attribute
    for objC in alist:
        print objC.name
        print objC.value

To test this function, we would have to mock class A. Without MagicMock, we would need to create a mock for multiple classes, like so:

class C:
    def __init__(self, name=None, value=None):
        self.name = name
        self.value = value

class B:
    def __init__(self):
        self.some_attribute = [] # this will be a list of instances of class C

class A:
    def __init__(self):
        self.objB = B()

Then to use this in your unit test:

import unittest

class RandomTests(unittest.TestCase):

    def test_dosomething(self):
        a = A()
        a.objB.some_attribute = [C('somename', 'somevalue')]
        dosomething(a)
        # then assert one output

All these just to pass the correction argument into the function dosomething so that it doesn’t complain about attribute errors.

But with magic mock, we don’t need to manually mock all our classes, and it just becomes:

import unittest
from mock import MagicMock

class RandomTests(unittest.TestCase):

    def test_dosomething(self):
        a = MagicMock()
        a.objB.some_attribute = [MagicMock(name='somename', value='somevalue')]
        dosomething(a)
        # then assert on output