检查测试期间 pytest 夹具是否被调用一次

San*_*ani 3 python pytest pytest-mock

是否提供诸如检查模拟是否实际被调用一次(或带有某些参数的一次)之pytest类的功能?unittest.mock

示例源代码:

my_package/my_module.py

from com.abc.validation import Validation


class MyModule:
    def __init__(self):
        pass

    def will_call_other_package(self):
        val = Validation()
        val.do()

    def run(self):
        self.will_call_other_package()
Run Code Online (Sandbox Code Playgroud)

上述源码的示例测试代码:

test_my_module.py

import pytest
from pytest_mock import mocker

from my_package.my_module import MyModule

@pytest.fixture
def mock_will_call_other_package(mocker):
    mocker.patch('my_package.my_module.will_call_other_package')


@pytest.mark.usefixtures("mock_will_call_other_package")
class TestMyModule:

    def test_run(self):
        MyModule().run()
        #check `will_call_other_package` method is called.

        #Looking for something similar to what unittest.mock provide
        #mock_will_call_other_package.called_once

Run Code Online (Sandbox Code Playgroud)

MrB*_*men 5

如果您想使用进行修补的固定装置,则可以将修补移动到固定装置中:

import pytest
from unittest import mock

from my_package.my_module import MyModule

@pytest.fixture
def mock_will_call_other_package():
    with mock.patch('my_package.my_module.will_call_other_package') as mocked:
        yield mocked
    # the mocking will be reverted here, e.g. after the test


class TestMyModule:

    def test_run(self, mock_will_call_other_package):
        MyModule().run()
        mock_will_call_other_package.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在测试中使用夹具参数。仅使用@pytest.mark.usefixtures不会让您访问模拟本身。如果您不需要在所有测试中访问模拟(或autouse=True在夹具中使用),您仍然可以使用它在类中的所有测试中有效。

另请注意,您在这里不需要pytest-mock- 但正如 @hoefling 所提到的,使用它可以使夹具更好地可读,因为您不需要子句with

@pytest.fixture
def mock_will_call_other_package(mocker):
    yield mocker.patch('my_package.my_module.will_call_other_package')
Run Code Online (Sandbox Code Playgroud)

顺便说一句:您不需要导入mocker. 灯具按名称查找,如果安装了相应的插件,则自动可用。

  • `mocker` 的优点是它会自动恢复测试拆卸时的修补,因此不需要 `with` 上下文。在我看来,这使得测试的缩进更少,更具可读性,但当然,这最终是一个品味问题。 (2认同)