Python Testing With a Mock Database

Minul Lamahewage
The Startup
Published in
4 min readJul 19, 2020
Photo by Maxwell Nelson on Unsplash

There are plenty of tutorials on the internet on using unittest but something I couldn’t find while doing a project was a tutorial on how to mock a database for testing.

I believe a similar method can be used for pytest as well.

When doing continual testing as the software is developed or improved upon, testing has to be done to ensure expected functionality.
There may be methods or functions that can alter the data in the database. When testing these functions, it’s best to use a separate database. It’s most definitely not recommended to use the production database while testing.

When testing is automated it’s not possible to manually change the database that each function is using. So, it’s necessary to patch in the test database to the production database. For that, we use the patch function available in the mock package. This is available in the Python standard library, available as unittest.mock, but for this tutorial, we’ll be using the mock package.

Requirements

You need the unittest package, patch from mock, and a mysql connector.

Setting up

I have two central functions that directly connect to the database, so all the patching will be done to these functions.

The above code is part of the production code. Therefore the config information in it will be of the production database.

During testing, we will be patching the config variable with the details of the test database.

So, with that out of way, let’s look at how we can set up the mock database.

Creating the MockDB class

For this, you need to have a MySQL server running on the system you wish to run the test on.
Every time a test suite is run, a temporary database is created and once the tests are completed, it is dropped.

First the imports

import mysql.connector
from mysql.connector import errorcode
from unittest import TestCase
from mock import patch
import utils

Here utils is the code given above named as utils.py

Since you’ll probably need to use the same test database for several test cases, it is easier to create a superclass. This superclass itself needs to be a subclass of the unittest.TestCase class.

class MockDB(TestCase):

Through this, MockDB class inherits four methods
1. SetUpClass()
2. SetUp()
3.TearDownClass()
4.TearDown()

These methods will help us “setup” a temporary database and “teardown” that database at the end.

SetUp() method runs before every test within a single class or test case. TearDown() method runs after every test within that test case. These are instance methods.

SetUpClass() and TearDownClass() are class methods. They run once for a single test case. That is, SetUpClass() will run before all the tests in the relevant test case and TearDownClass() will run after all the tests are done.

You can choose to use either of these two methods depending on the requirement. If you need the database to set up for each test then the first method is best suited for you. If you can manage with the database being set up only once then the second method is better suited. One thing to note is that the first method will result in slower tests. Depending on the number of tests you have, it will continue to become slower. The second method in comparison will be significantly faster. For this tutorial, I’ll be using the second method.

Creating the SetUpClass method

First, we define our database connection. Then we check if the database is already created and drop it if it has been.

Afterwards, we create the database, create the necessary tables and insert data to those tables.

Patching config

Once setting up the test database is done, we need to create a config variable with the test database information to patch the production database.

testconfig holds the details of the test database. mock_db_config is used to patch the config variable in the utils file with testconfig. Since these are dictionaries, patch.dict is used.

Creating the TearDownClass method

Next, we need the tearDownClass method. All this needs to do is drop the test database.

MockDB Class

Here is the entire MockDB class.

Once MockDB class is done, we can inherit this class to create test cases.

Testing

We’ll write tests to test the functions in utils.py.

We need to import the file we are planning to test, the MockDB class and patch from import

import utils
from mock_db import MockDB
from mock import patch

When using the patch for the config variable, the following has to be used,

with self.mock_db_config:

Any code that is executed within this, will use the patched config variables.

Here is the completed test_utils code with some sample tests

I hope this provided you with a basic understanding of how to use a mock database for testing with unittest. This tutorial is aimed at providing users with a foundation on mocking a database for testing. Your implementation of this will depend on factors such as the use of an ORM for example.

--

--

Minul Lamahewage
The Startup

3rd year Computer Science and Engineering undergraduate at University of Moratuwa, Sri Lanka