如何使用pytest装置优雅地模拟类?

2024-05-16 09:29:50 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个fixture来模拟一个使用monkeypatch的类

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

现在,我必须在我的测试中使用这个夹具,以便模拟这个类

#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

正如您在标记行中所看到的,我必须在每个函数中导入此模块dummypackage,以确保在导入模块之前应用该装置(否则该装置将无效)

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

有没有更优雅的方法来实现这一点


Tags: 模块函数pytestimportpytestdeffunction
1条回答
网友
1楼 · 发布于 2024-05-16 09:29:50

注释: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()

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

相关问题 更多 >