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 ,而我不想这样做。
您无需更改任何内容。
您可以将
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
使用 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
的一个原因是避免向代码库添加额外的依赖项,从而增加维护负担。