【问题标题】:How to elegantly mock a class using pytest fixtures?如何使用 pytest 设备优雅地模拟一个类?
【发布时间】:2020-08-19 19:30:01
【问题描述】:

假设我有一个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 似乎也不是很优雅。

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

【问题讨论】:

  • dummypackage 可以在test_dummy.py 之上导入,dummyclass 将被成功修补。不过,from dummypackage import dummyclass 不起作用。究竟是什么不工作,所以你诉诸移动进口?

标签: python pytest fixtures


【解决方案1】:

评论: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()

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

【讨论】:

  • 感谢您的回复,但这并不能回答我的问题。我的问题是关于模拟整个类,而不是方法或函数。
  • 你可以用同样的方式模拟一个类。只需将join 替换为类名即可。当然还有模块。
  • monkeypatch 维护得很好,因为它是由pytest 提供的夹具。
  • @hoefling 公平点,我把它误认为是同名的图书馆。我将修改/删除我的评论。
  • @de1;由于各种原因,我需要使用monkeypatch 固定装置; unittest.mock 不起作用
猜你喜欢
  • 2020-12-20
  • 2011-02-14
  • 2021-03-26
  • 1970-01-01
  • 2018-12-12
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 2019-04-22
相关资源
最近更新 更多