You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单元测试中无法Mock函数的问题求助

Mock函数失效的原因及修正方案

核心错误点

  1. Fixture的yield位置错误:你把yield写在了patch的with块外面,with块退出时会自动恢复原函数,导致测试执行时Mock已经失效。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:40:10