在函数 pytest 中模拟函数?

问题描述 投票:0回答:2
def func1():
    return 5
    
def func2(param1, param2):
    
    var1 = func1()
    return param1 + param2 + var1

我想使用 pytest 通过模拟第一个函数来测试第二个函数,但我不知道该怎么做。

@pytest.fixture(autouse=True)
def patch_func1(self):
    with mock.patch(
        "func1",
        return_value= 5,
    ) as self.mock_func1:
        yield

我认为可以通过上面的依赖注入和固定装置来完成,但这意味着更改 func1 ,而我不想这样做。

python python-3.x function pytest
2个回答
10
投票

您无需更改任何内容。

您可以将

mocker
夹具与
pytest
一起使用(需要安装 pytest-mock)。不用担心
mocker
的争论,它会神奇地起作用。

def test_func2(mocker):
    mocked_value = 4
    first = 1
    second = 2
    func1_mock = mocker.patch("func1")
    func1_mock.return_value = mocked_value
    actual_value = func2(first, second)
    assert actual_value == first + second + mocked_value

0
投票

使用 pytest 的内置固定装置而不是单独的包来替代 pytest-mock 的是 monkeypatch 固定装置。

from my_module import func2


def test_func2(monkeypatch):
    mocked_value = 4
    # create a function that returns the desired mock value
    def mock_func_1():
        return mocked_value
    # patch the module with the mocked function
    monkeypatch.setattr(my_module, "func1", mock_func_1)
    first = 1
    second = 2
    actual_value = func2(first, second)
    assert actual_value == first + second + mocked_value

pytest-mock
monkeypatch
之间的一个区别是,
monkeypatch
在运行时在测试环境中全局更改模拟函数的行为,而
pytest-mock
仅在单个测试的范围内这样做。如果您总是要在执行该函数的测试中显式模拟该函数(正如您应该做的那样),那么根据我的经验,这不是问题。但这是一个潜在的陷阱,也是选择
pytest-mock
的可能原因。另一方面,选择
monkeypatch
的一个原因是避免向代码库添加额外的依赖项,从而增加维护负担。

© www.soinside.com 2019 - 2024. All rights reserved.