[英]How to elegantly mock a class using pytest fixtures?
Let's say I have a fixture
to mock a class using monkeypatch
.假设我有一个使用 monkeypatch 模拟
monkeypatch
的fixture
。
# conftest.py
@pytest.fixture
def mock_dummyclass(monkeypatch):
def mock_function():
return None
monkeypatch.setattr(dummypackage, "dummyclass", mock_function)
Now, I have to use this fixture in my test so that this class is mocked.现在,我必须在我的测试中使用这个夹具,以便模拟这个 class。
#test_dummy.py
@pytest.mark.usefixtures("mock_dummyclass")
class TestManyDummyMethods:
def test_dummy_one():
import dummypackage # Flag A
def test_dummy_two():
import dummypackage # Flag B
...
def test_dummy_n():
import dummypackage # Flag N
As you can see in the flagged lines, that I'll have to import this module dummypackage
inside every function to ensure that the fixture is applied before the module is imported (otherwise the fixture would not be effective).正如您在标记行中看到的那样,我必须在每个 function 中导入此模块
dummypackage
以确保在导入模块之前应用夹具(否则夹具将无效)。
Importing dummypackage
inside the class would work but calling self.dummypackage
inside functions doesn't seem very elegant either.在 class 中导入
dummypackage
会起作用,但在函数内部调用self.dummypackage
似乎也不是很优雅。
Is there a more elegant way to achieve this?有没有更优雅的方法来实现这一目标?
Comment: The monkeypatch
library doesn't seem to be maintained anymore.评论: monkeypatch
库好像没人维护了。unittest.mock
should probably offer all you need.unittest.mock
应该可以提供你所需要的一切。
I would try to avoid a solution that depends on importing the module as part of your test because that would break if it was imported for another reason (eg import other functions).我会尽量避免依赖于导入模块作为测试的一部分的解决方案,因为如果它是出于其他原因导入的(例如导入其他函数),那将会中断。
I am using os
as an example as that exists and makes it reproducible.我以
os
为例,因为它存在并使其可重现。
How best to patch seem to depend on how you import from another module.如何最好地修补似乎取决于您如何从另一个模块导入。
target_module1.py
(importing the join
method from os.path
):target_module1.py
(从os.path
导入join
方法):from os.path import join
def some_method_using_join():
return join('parent', 'child')
This requires us to patch the join
method of target_module1.py
:这需要我们修补
target_module1.py
的join
方法:
target_module1_test.py
: target_module1_test.py
:
from unittest.mock import patch, MagicMock
import pytest
from target_module1 import some_method_using_join
@patch('target_module1.join')
def some_test(join_mock: MagicMock):
some_method_using_join()
target_module2.py
(importing the os
module):target_module2.py
(导入os
模块):import os
def some_method_using_join():
return os.path.join('parent', 'child')
This allows us to patch the join
method on os.path
:这允许我们修补
os.path
上的join
方法:
target_module2_test.py
: target_module2_test.py
:
from unittest.mock import patch, MagicMock
import pytest
from target_module2 import some_method_using_join
@patch('os.path.join')
def some_test(join_mock: MagicMock):
some_method_using_join()
This assumes that you don't need to patch a class or method that is used at the module level (ie while importing).这假定您不需要修补 class 或在模块级别(即导入时)使用的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.