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.