Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyTest: Patch a method where the module was imported using 'importlib.import_module()'

How can I patch a method in a class, where the module containing the class is imported using importlib.import_module()?

The reason for using importlib.import_module() is because the package to which the module belongs contains a -, and as I don't control the package I am unable to change that.

I have attempted to patch the method by targeting it directly, and by targeting it though the name of the imported module, but neither works and the assertion in test_someclass.py fails.

File Structure

my-package
 | some_module.py
tests
 | conftest.py
 | test_some_module.py.py

conftest.py

I've tried to patch the method by targeting it directly, and by targeting it though the name of the imported module, but neither works and the assertion in test_someclass.py fails.

import pytest
import importlib
module = importlib.import_module('some-package.some_module')
SomeClass = module.SomeClass

@pytest.fixture(scope='function')
def patch_some_module(mocker):

    def some_module():
        return "I'm fake :("

    path1 = 'some-package.some_module.SomeClass.some_method'
    path2 = 'module.SomeClass.some_method'
    mocker.patch(path1, some_module)
    mocker.patch(path2, some_module)

some_module.py

The module in question contains a class with a method that I wish to mock.

class MyClass:

    def my_method(self):
        return "I'm real!"

test_some_module.py

from conftest import SomeClass

def test_some_method():

text = SomeClass().some_method()
expected = "I'm fake :("

assert text == expected

Test Failure

As described above, even with my attempts to patch the some_method method, the test still fails.

================================= test session starts ==================================
platform linux -- Python 3.8.10, pytest-7.0.1, pluggy-1.0.0
rootdir: /home/me/pytest_question
plugins: requests-mock-1.9.3, cov-3.0.0, env-0.6.2, mock-3.7.0
collected 1 item

tests/test_some_module.py F                                                      [100%]

======================================= FAILURES =======================================
___________________________________ test_some_method ___________________________________

    def test_some_method():

        text = SomeClass().some_method()
        expected = "I'm fake :("

>       assert text == expected
E       assert "I'm real!" == "I'm fake :("
E         - I'm fake :(
E         + I'm real!

tests/test_some_module.py:8: AssertionError
=============================== short test summary info ================================
FAILED tests/test_some_module.py::test_some_method - assert "I'm real!" == "I'm fake :("
================================== 1 failed in 0.05s ===================================
like image 657
David Gard Avatar asked Aug 25 '26 19:08

David Gard


1 Answers

You don't seem to be using your fixture in tests/test_some_module.py

Try changing it to the following.

# tests/test_some_module.py

from conftest import SomeClass


@pytest.mark.usefixtures("patch_some_module")
def test_some_method():
  text = SomeClass().some_method()
  expected = "I'm fake :("

  assert text == expected
like image 55
Yassine El Bouchaibi Avatar answered Aug 27 '26 08:08

Yassine El Bouchaibi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!