繁体   English   中英

如何使用 pytest fixtures 优雅地模拟 class?

[英]How to elegantly mock a class using pytest fixtures?

假设我有一个使用 monkeypatch 模拟monkeypatchfixture

# conftest.py
@pytest.fixture
def mock_dummyclass(monkeypatch):
    def mock_function():
        return None
 
    monkeypatch.setattr(dummypackage, "dummyclass", mock_function)

现在,我必须在我的测试中使用这个夹具,以便模拟这个 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

正如您在标记行中看到的那样,我必须在每个 function 中导入此模块dummypackage以确保在导入模块之前应用夹具(否则夹具将无效)。

在 class 中导入dummypackage会起作用,但在函数内部调用self.dummypackage似乎也不是很优雅。

有没有更优雅的方法来实现这一目标?

评论: monkeypatch库好像没人维护了。 unittest.mock应该可以提供你所需要的一切。

我会尽量避免依赖于导入模块作为测试的一部分的解决方案,因为如果它是出于其他原因导入的(例如导入其他函数),那将会中断。

我以os为例,因为它存在并使其可重现。

如何最好地修补似乎取决于您如何从另一个模块导入。

示例 1: target_module1.py (从os.path导入join方法):

from os.path import join

def some_method_using_join():
    return join('parent', 'child')

这需要我们修补target_module1.pyjoin方法:

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()

示例2: target_module2.py (导入os模块):

import os

def some_method_using_join():
    return os.path.join('parent', 'child')

这允许我们修补os.path上的join方法:

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()

这假定您不需要修补 class 或在模块级别(即导入时)使用的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM