pytest 5.0.1python 3.6
想象一下,你有一个类,你导入并在另一个类中初始化
from file import Client
class A()
def __init__(self):
self.client = Client()
def call(self):
self.client.execute()
现在,当我想测试它时,因为这个导入类涉及外部组件(例如数据库(,我想嘲笑它的发生(例如,我不敢相信你读数据库这么慢…(。所以我有一个带补丁的固定装置。耶!
@pytest.fixture
def setup_a(self):
with patch('path_to_patch') as patched:
a = A()
return a
然而,我似乎无法从fxiture中获得补丁来使用它。我尝试创建一个新的补丁,但这不起作用(例如断言False(
@patch('path_to_patch')
def test_successful_execution(self, new_patch, setup_a):
setup_a.call()
assert new_patch.execute.called
我也尝试过隐式使用上面的补丁
@patch('path_to_patch')
def test_successful_execution(self, new_patch, setup_a):
setup_a.call()
assert setup_a.execute.called
做这件事的正确方法是什么?如果你需要更多的解释,请告诉我。
我假设您想在A
中修补Client.execute
,并且fixture将返回一个类型为A
的对象,并且该修补已就位。第一件事是确保补丁仍然有效:
@pytest.fixture
def mocked_a(self):
with patch('path_to_a.Client.execute'):
yield A()
在您的示例中,对象在修补作用域之后返回,这意味着修补已经在该点结束。还要注意,您必须修补在a
模块中导入的Client
模块(假设A
就是在这里定义的(。
要使用修补的对象,您现在可以:
def test_successful_execution(mocked_a):
mocked_a.call()
mocked_a.Client.execute.assert_called_once()
请注意,您可以以模拟的方式访问模拟。
或者,您可以在fixture中返回mock本身:
@pytest.fixture
def mocked_execute(self):
with patch('path_to_a.Client.execute') as patched:
yield patched
def test_successful_execution(mocked_execute):
a = A()
a.call()
mocked_execute.assert_called_once()
通过这种方式,您可以在测试中明确地创建对象,在我看来,测试更加清晰。
(这是我想不出来的,所以可能有错误…(