单元测试中无法Mock函数的问题求助
Mock函数失效的原因及修正方案
核心错误点
- Fixture的yield位置错误:你把
yield写在了patch的with块外面,with块退出时会自动恢复原函数,导致测试执行时Mock已经失效。 - Mock路径不符合规则:Mock的关键原则是在哪里调用函数,就patch哪里,不是函数定义的位置,而是被测试代码引用该函数的位置。
修正后的测试代码
假设你的main.py中正确导入了两个函数:
# foo/bar/main.py from .baz import function1_to_mock, function2_to_mock def some_function(): function1_to_mock() function2_to_mock()
测试代码修正如下:
from unittest.mock import patch import pytest from foo.bar.main import some_function MOCKED_VALUE = "mocked_result" @pytest.fixture def mock_dependencies(): # patch main.py中实际引用的函数,而非原模块的定义 with patch('foo.bar.main.function1_to_mock') as mock_func1, \ patch('foo.bar.main.function2_to_mock') as mock_func2: mock_func1.return_value = MOCKED_VALUE mock_func2.return_value = {'this': 'that'} # yield放在with块内,确保测试执行期间patch持续生效 yield mock_func1, mock_func2 def test_main(mock_dependencies): mock_func1, mock_func2 = mock_dependencies some_function() # 验证Mock函数被正确调用 mock_func1.assert_called_once() mock_func2.assert_called_once()
关于Mock路径的补充说明
如果需要测试baz.py中function2_to_mock内部调用的function1_to_mock(即验证function2_to_mock是否调用了function1_to_mock),此时要patch的是baz.py本地的function1_to_mock:
from unittest.mock import patch from foo.bar.baz import function2_to_mock def test_function2_calls_function1(): with patch('foo.bar.baz.function1_to_mock') as mock_func1: function2_to_mock() # 验证function2_to_mock确实调用了function1_to_mock mock_func1.assert_called_once()
关键总结
- 永远记住:patch函数被引用的位置,而非定义的位置。
- Fixture中使用
patch时,yield必须处于with块的缩进范围内,否则测试开始前Mock就已经被恢复。
内容的提问来源于stack exchange,提问作者Norman Robins
相关产品推荐
相关产品推荐

