Mocking python code with magickmock.

The objective of mocking an object, a function call or a entirely class is to convert it runtime behavior, to some behavior that we can define during the test implementation. In other words, we substitute the original implementation by a Mock instance, that can returns some value, a new function or a new Mock instance. It's easy to find on the internet several articles and stackoverflow discussions about the best approaches when we have to mock code. This post does not have the intention to be a guide to the Mock library, but a resume of how I fixed a problem of dependencies between some API tests of a personal project.

The problem

I already have talked about kiskadee, a project that I developed during my GSoC program. I'm refactoring it and rewriting tests, because the code was too coupled and little cohesive. In the process of refactoring and running tests I came across the following problem:

sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError)
duplicate key value violates unique constraint "fetchers_name_key"
DETAIL:  Key (name)=(kiskadee-fetcher) already exists.
[SQL: 'INSERT INTO fetchers (name, target, description)
VALUES (%(name)s, %(target)s, %(description)s)
RETURNING'] [parameters:
{'name': 'kiskadee-fetcher',
'target': 'university', 'description': None}]

Every time that some of my tests broke, sqlalchemy trigger the error above, avoiding the subsequent tests to run properly. This was happening because my setUp method (a special unittest method, that is executed before every test on the test suite) always tries to repopulate the test database with some data, but this only work well when the test ends and the tearDown method (a special unittest method, that is executed after every test on the test suite) is called. The tearDown method should removes the data created by the previous test, making the test database clean for the next test, but if some test brakes, the tearDown method is not called, the database is not cleaned, and the next test will run in a dirty database. Tests have to be isolated. A test should not depend on some data created by a previous one. That's why the setUp and tearDown methods exists, to help developers to make their tests independently, but in the way that I had implemented my tests, this was not happening.

Here is a code snippet retrieved from kiskadee code. On the setup I create a test database session, create the database tables, create a fetcher object, and save it on the database. On the tearDown method I remove all the tables. The idea behind this code was recreate, for every test, some sample data on the database, in order to be used by the tests.

def setUp(self): = True
        self.engine = kiskadee.database.Database('db_test').engine
        Session = sessionmaker(bind=self.engine)
        self.session = Session()
        fetcher = kiskadee.model.Fetcher(name='kiskadee-fetcher',

def tearDown(self):

As I said, the main problem with this approach is that if a test brakes, the tearDown method is not called, but the setUp method will be called for the next test, and this will cause the sqlalchemy error. Thinking in a solution for that, I noticed that all tests that had this problem was not unit tests. I was not testing if a object is properly saved on database. I was testing code that in some point retrieve data from the database, and use this data to execute some task. Basically, I was running functional and integration tests, so I could perfectly mock the database calls.


According to the python documentation, unittest.mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. MagickMock is a Mock subclass with default implementations of most of magic methods. Let's check some code:

>> from unittest.mock import MagicMock
>> foo = MagickMock()
>> foo
<MagicMock id='139787927657832'>
>> foo()
<MagicMock name='mock()' id='139787911958936'>
>> foo().bar
<MagicMock name='mock().bar' id='139787911975600'>
>> foo()
<MagicMock name='mock()' id='139787911984016'>
>> is_instance(foo, MagicMock)
>> is_instance(foo(), MagicMock)
>> is_instance(foo().bar, MagicMock)

foo now is an MagicMock object, and this makes available to us some interesting methods, very useful when we are mocking code on tests. Notice that every method or attribute that we call from foo, will returns an unique MagicMock object. This is all great, but a MagicMock object as return of a method call is not very useful, if you want that this call returns a specific value. For that we can use the return_value argument, when creating a new MagicMock object.

>> from unittest.mock import MagicMock
>> foo = MagickMock(return_value=5)
>> foo
<MagicMock id='139787927657832'>
>> foo()
>> foo('new_arg')

Every time that your code calls foo(), the method will returns 5, independently of which arguments the method receives. But if we need to return some specific value based on what arguments our function receives? We can use side_effect:

>> from unittest.mock import MagicMock
>> foo = MagickMock(side_effect=lambda x: x**x)
>> foo
<MagicMock id='139787927657832'>
>> foo(5)
>> foo(10)

The side_effect argument must be a function, that will be executed when the mocked method is called.

Fixing the problem

Now that we know how MagicMock works, lets go back to kiskadee code. Architecturally speaking, kiskadee works like this:

Diagram 1: Kiskadee architecture.

My initial objective was to test the response of kiskadee's api. The tests before using the Mock library, create several data on database, in order to the endpoints have something to retrieve and respond, but if the database is empty, the api still is able to respond, but with an empty response. This means that how this data is retrieved from the api, is not so important. What really matters is that the api must have some data to respond, when some endpoint is requested. This is the perfect scenario to use Mock.

The next snippet is one of the tests that are using MagicMock to replace a sqlalchemy query by an MagicMock object. When the api calls the sqlalchemy query, instead of runing a select on the database and retrieve some data, the api will actually execute the Mock object, and returns what we define as a return value when mocked the sqlalchemy query. With that approach I don't need to save nothing on the database. This avoid us to execute unnecessary code, as Model validations and sqlalchemy restrictions, what is great because this is not what we want to test.

def test_get_analysis_results(self):

    analysis = kiskadee.model.Analysis(
            id=1, analyzer_id=1, version_id=1,
            raw={'results': 'first analysis results'}
            ) = MagicMock(
    response ="/analysis/kiskadee-package/7.23/1/results")
    response_data = json.loads("utf-8"))
    self.assertIn("analysis_results", response_data)
    self.assertTrue(len(response_data["analysis_results"]) > 0)

This is the code that the snippet above will test:

def analysis_reports(pkg_name, version, analysis_id):
"""Get the analysis reports from a specific analyzer."""
db_session = kiskadee_db_session()
analysis = db_session.query(Analysis).get(analysis_id)
data, errors = AnalysisSchema(only=['report']).dump(analysis)
report = data['report']
        report['results'] = json.loads(report['results'])
        return jsonify({'analysis_report': report})
except Exception as err:
        return jsonify({'analysis_report': {}})

When the db_session.query(Analysis).get(analysis_id) is executed, our mock object will be called, and will returns the analysis object that we defined on the functional test.


Mocking is a great technique, that can save a lot of code when writing tests. It permit us to isolate parts of the code that we want to test, and focus on what really matters, but it must be used with wisdom. If you have to mock to much code to be able to test something, this can be an indication that your code design was not well planned. Another case that should not requires the use of mock is unit tests. Unit tests must test units of code, code that must be self contained, so technically is a level of test that should not requires you to mock code. The next step using the Mock library, is to move all sqlalchemy queries used to interact with kiskadee's database to methods with interfaces owned by kiskadee. This post explains well why we must do that.