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 ===================================
>Solution :
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