An Nguyen
An Nguyen

Reputation: 403

pytest-mock - Mock a function from a module

I have an util in my module engine.py, which is imported from another file:

from main.utils.string import get_random_string

def generate_random_string():
    return get_random_string()

In my test file:

def test_generate_random_string(mocker):
    mocker.patch('main.utils.string.get_random_string', return_value='123456')

However, it's still trying to use the real implementation of string.get_random_string instead of the mock that I've created, unless I change my engine.py to:

from main.utils import string

def generate_random_string():
    return string.get_random_string()

How can I achieve the mocking part without importing the whole string module to engine.py?

Upvotes: 17

Views: 18953

Answers (2)

Stefan
Stefan

Reputation: 12242

While trying to patch a module function with

@patch('utils.collection_utils.min_object', return_value='mocked_min_object_result')

I had to change the import for my using class from

from utils.collection_utils import min_object
... 
min_object(...)

to

from utils import collection_utils
...
collection_utils.min_object(...)

Also note that using a patch might change the order of arguments for the test method. Instead of

@patch('utils.collection_utils.min_object', return_value='mocked_min_object')
def test_process_with_min_production_cost(sut):

then

@patch('utils.collection_utils.min_object', return_value='mocked_min_object')
def test_process_with_min_production_cost(patched_min_object, sut):

Upvotes: 1

An Nguyen
An Nguyen

Reputation: 403

I have successfully achieved it by changing mocker.patch('main.utils.string.get_random_string', return_value='123456') to mocker.patch('engine.get_random_string', return_value='123456').

Details can be found here.

Upvotes: 20

Related Questions