How to mock imported module class in pytest

82 views Asked by At

I have this files.

  • main.py
  • util.py
  • mocking_util.py
  • test_main.py

I'd like to use mocking_util.py instead of util.py in test code.

I know mocker.patch("util.my_something1", return_value = 1) but it only works at function level.

How can I mock an entire module?

main.py

from . import util.py

def something1(a, b):
    return util.my_something(a, b)

def something2(a, b):
    return util.my_something2(a, b)

def something3(a, b):
    return util.my_something3(a, b)

util.py

def my_something1(a, b):
    return a + b

def my_something2(a, b):
    return a + b + 1

def my_something3(a, b):
    return a + b + 2

mocking_util.py

def my_something1(a, b):
    return 1

def my_something2(a, b):
    return 1

def my_something2(a, b):
    return 1

test_main.py

import main

def test_case1(mocker):
    # I'd like to use mocking_util.py instead of util.py
    # What should I do for this?

    result = main.something1(10, 10)
    assert result == 1

    result = main.something2(10, 10)
    assert result == 1

    result = main.something3(10, 10)
    assert result == 1
1

There are 1 answers

0
Karine Bauch On BEST ANSWER

Using pytest-mock

pip install pytest-mock

Patch the util module in the main module with mocking_util

import main
import mocking_util


def test_case1(mocker):
    
    mocker.patch('main.util', mocking_util)

The mocker fixture allows you to access the unittest.mock.patch symbol.

unittest.mock.patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

The target is imported and the specified object replaced with the new object [passed in new].

Now when main calls util.my_something, it will call mocking_util.my_something

    
    result = main.something1(10, 10)
    assert result == 1

    result = main.something2(10, 10)
    assert result == 1

    result = main.something3(10, 10)
    assert result == 1