pytest 模拟补丁 side_effect 与 pytest.mark.parametrize 一起使用时不会迭代

pytest mock patch side_effect not iterate when used together with pytest.mark.parametrize

我有下面的 pytest 脚本,side_effect[2, 6] 没有被迭代。在测试函数 test_my_function.

中总是卡在值 2

我的问题是:

如何使 side_effect 值与函数 test_my_function 中的 parametrize 个测试用例一起迭代。 (假设我们必须使用 parametrize)。

#!/usr/bin/env python3
#

import pytest

def my_function(x):
    return x*2

@pytest.fixture
def mock_my_function(mocker):
    mocker.patch(
        __name__ + ".my_function", side_effect=[2, 6]
    )

@pytest.mark.parametrize("input, expect", [(1, 2), (3, 6)])
def test_my_function(input, expect, mock_my_function):
    assert expect == my_function(input)

    

首先,如果您模拟要测试的函数,那么您的测试实际上并没有测试任何东西

其次,每次调用测试函数时都会设置函数范围的固定装置——对于每个参数化案例集,它将运行你的固定装置

这意味着(在您的示例中)您的测试的两次调用都将 my_function 模拟为 return 2,因为唯一发生的调用是

如果您想对模拟函数进行额外参数化,我建议将其包含在您的参数化列表中:

@pytest.mark.parametrize(
    ('input', 'expect', 'mocked_ret'),
    (
        (1, 2, 2),
        (3, 6, 6),
    ),
)
def test_my_function(input, expect, mocked_ret, mocker):
    mocker.patch(f"{__name__}.my_function", return_value=mocked_ret)

    assert my_function(input) == expect

免责声明:我是 pytest 核心开发人员