NonePytest - конструктор-пересмешник внутри конструктора
Все,
У меня есть класс, похожий на этот.
from mod import Bar
class Foo:
def __init__(self):
self.obj = Bar()
Как мне издеваться Bar
конструктор, использующий pytest / pytest-mock? Я попытался следующее безуспешно.
def test():
with mock.patch('mod.Bar') as patched:
Foo()
2 ответа
Вы должны исправить имя, а не экземпляр.
Из официальной документации Python: где патчить
patch() работает (временно) изменяя объект, на который указывает имя, с другим. Может быть много имен, указывающих на какой-либо отдельный объект, поэтому для исправления необходимо убедиться, что вы исправили имя, используемое тестируемой системой.
В вашем примере ваш класс Foo
определяется в модуле foomod.py
так что надо исправлять foomod.Bar
вместо mod.Bar
,
Вы можете поместить это в прибор, используя mocker
крепление от pytest-mock
или с 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
Насколько мне известно, между этими двумя подходами нет существенной разницы. Оба очищаются, когда прибор выходит из области видимости.
Я использую следующее, чтобы имитировать объекты с помощью
pytest
без
fixture
декоратор
# 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!'