Python Unit Test : How to unit test the module which contains database operations?

user2301 picture user2301 · Nov 7, 2017 · Viewed 17.4k times · Source

I am using pymysql client library to connect to the real database. I have a function in module, where I connect to the database using pymysql and do only database insert operations.How to unit test this function in python without hitting the real database?

import pymysql

def connectDB(self):

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='user',
                             password='passwd',
                             db='db')

try:
    with connection.cursor() as cursor:
        # Create a new record
        sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
        cursor.execute(sql, ('[email protected]', 'newpassword'))


    connection.commit()

My python version is 2.7.

Answer

uwevil picture uwevil · Nov 7, 2017

You can use patch, like this:

from unittest.mock import patch, MagicMock

@patch('mypackage.mymodule.pymysql')
def test(self, mock_sql):
    self.assertIs(mypackage.mymodule.pymysql, mock_sql)

    conn = Mock()
    mock_sql.connect.return_value = conn

    cursor      = MagicMock()
    mock_result = MagicMock()

    cursor.__enter__.return_value = mock_result
    cursor.__exit___              = MagicMock()

    conn.cursor.return_value = cursor

    connectDB()

    mock_sql.connect.assert_called_with(host='localhost',
                                        user='user',
                                        password='passwd',
                                        db='db')

    mock_result.execute.assert_called_with("sql request", ("user", "pass"))