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

问题描述

假设我有一个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看起来也不太好。

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

解决方法

注释:monkeypatch库似乎已不再维护。 unittest.mock应该可以满足您的所有需求。

我会尽量避免依赖于将模块作为测试的一部分导入的解决方案,因为如果由于其他原因(例如,导入其他功能)而导入该模块,则该解决方案会失效。

我使用os作为例子,它已经存在并且可以再现。

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

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

from os.path import join

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

这需要我们修补join的{​​{1}}方法:

target_module1.py

target_module1_test.py

示例2: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模块):

os

这使我们可以在import os def some_method_using_join(): return os.path.join('parent','child') 上修补join方法:

os.path

target_module2_test.py

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...