gold_cy
gold_cy

Reputation: 14236

Unit Testing involving databases

Suppose I have a directory

  home/user/my_python_scripts/
                   /src
                       /my_script.py
                   /tests
                      /test_my_script.py

I am running some unit tests to test my_script.py from the ~/my_python_scripts/test directory. I am importing the function from my_script in to my test_my_script.py.

The problem however arises since the function in my_script.py imports two other functions from another script. Those two functions query a database for specific data. I am mocking and patching these two functions in my test script however when I run pytest on this script the function ends up querying the database regardless. I looked at the two functions that my_script.py uses. Each of them queries a different database and furthermore one of the functions ends up using three other functions that live in the same file as it does.

Am I not accounting for these functions and/or database properly in my unit test? I cannot share the code since it is proprietary but I am more than happy to share my unit test code below:

from pytest_mock import mocker

params = [(3141, 55)]
raw_data = [{'a': 'fizz', 'b': 'buzz', 'c': 'foo', 'd': 'hello'}]
descriptors = ['taxi', 3141, 55, 1]

def test_get_data(mocker):
    setattr(get_data, 'get_raw_data', params)
    mocker.patch.object(get_data, 'get_raw_data')
    get_data.get_raw_data.return_value = params
    setattr(get_data, 'get_data_by_day', raw_data)
    mocker.patch.object(get_data, 'get_data_by_day')
    get_data.get_data_by_day.return_value = raw_data
    assert get_data('taxi', 3141, '1', '3') == raw_data, descriptors

Looking for any advice as well as tips.

Upvotes: 2

Views: 135

Answers (1)

gold_cy
gold_cy

Reputation: 14236

So I figured it out. I was not correctly setting the values on the patched mock functions. This is the code that ended up working properly.

from mock import patch
from .relative.path import get_data

params = [(3141, 55)]
raw_data = [{'a': 'fizz', 'b': 'buzz', 'c': 'foo', 'd': 'hello'}]
descriptors = ['taxi', 3141, 55, 1]

@patch.object(get_data, 'get_raw_data')
@patch.object(get_data, 'get_data_by_day')
def test_get_stuff_1(mock_get_data_by_day, mock_get_raw_data):
    mock_get_data_by_day.return_value = raw_data
    mock_get_raw_data.return_value = params
    result = get_data.get_stuff('taxi', 3141, '1', '3')
    assert result == (raw_data, descriptors)

I import the script get_data.py as an object, and then patch each function get_raw_data and get_data_by_day as attributes of this object. Then when I run the unit test on the mock values I provide it returns the results I expect.

Upvotes: 1

Related Questions