I am trying to write unit tests for my python project using pytest. I have a module from another repo called sql_services. Within sql_services there is a function called read_sql that I am trying to mock.
So far, I have only been able to mock the function if I import the module like
import sql_services
and invoke sql_services.read_sql but I have been unable to mock it if I import the function like
from sql_services import read_sql
This is a problem because my codebase uses the latter method for importing the functions
Here is the function I am trying to write a unit test for:
from sql_services import read_sql
def foo():
df = read_sql("SELECT * FROM schema.table")
return df
Here is the unit test file I have so far:
import pytest
import unittest.mock as mock
import pandas as pd
import sql_services
from entry import foo
@mock.patch("sql_services.read_sql")
def test_read_sql(mock_read_sql):
mock_read_sql.return_value = pd.DataFrame()
df = sql_services.read_sql("SELECT * FROM schema.table")
assert df.empty
@mock.patch("sql_services.read_sql")
def test_do_a_read(mock_read_sql):
mock_read_sql.return_value = pd.DataFrame()
df = foo()
assert df.empty
The first test passes and the second fails because it actually reads the data frame from the database. Is there any way I can mock the function from within foo without refactoring my entire codebase?
You just patch the correct name:
@mock.patch("entry.read_sql")
def test_read_sql(mock_read_sql):
mock_read_sql.return_value = pd.DataFrame()
df = sql_services.read_sql("SELECT * FROM schema.table")
assert df.empty]
entry.foo
is using the global variable entry.read_sql
to access the function you want to mock, not the global variable sql_servies.read_sql
.