All,
I have a class similar to this.
from mod import Bar
class Foo:
def __init__(self):
self.obj = Bar()
How do I mock the Bar
constructor using pytest / pytest-mock? I have tried the following unsuccessfully.
def test():
with mock.patch('mod.Bar') as patched:
Foo()
You have to patch the name, not the instance.
From the official Python documentation: Where to patch
patch() works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.
In your example, your class Foo
is defined in a module foomod.py
, so you have to patch foomod.Bar
instead of mod.Bar
.
You can put this into a fixture by using the mocker
fixture from pytest-mock
or with unittest.mock.patch
.
@pytest.fixture # With pytest-mock
def mock_bar(mocker):
return mocker.patch('foomod.Bar')
@pytest.fixture # With stdlib
def mock_bar():
with patch('foomod.Bar') as mock:
yield mock
# Usage
def test_foo(mock_bar):
pass
To my knowledge, there is no significant difference between the two approaches. Both are cleaned up when the fixture goes out of scope.
I use the following to mock objects with pytest
without the fixture
decorator
# path.to.MyClass
class MyClass():
def __init__(self, some_parameter: SomeObject) -> None:
self.some_value = some_parameter
def get_something(self) -> str:
return 'Hello'
# tests.py
from pytest_mock.plugin import MockerFixture
from unittest.mock import MagicMock
def test_with_mock(mocker: MockerFixture) -> None:
mock_myclass: MagicMock = mocker.patch('path.to.MyClass')
mock_myclass_get_something: MagicMock = mocker.patch('path.to.MyClass.get_something')
mock_myclass_get_something.return_value = 'World!'
assert mock_myclass.get_something() == 'World!'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With