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

Pytest Fixture模拟对象未传入被测函数,触发AssertionError

问题解决思路与修复方案

核心问题定位

  • Mock未生效:被测代码直接导入并实例化github.MainClass.Github,测试中的mock未正确拦截该导入路径
  • Token类型错误:mock返回的git_token为整数12121212,不符合Github构造函数对login_or_token的字符串类型要求
  • 导入时机错误:测试代码在mock前就导入了被测模块,导致真实类被提前加载
  • Fixture依赖问题:fixture依赖关系配置不当,mock未在被测代码执行前生效

具体修复步骤

1. 修正Mock路径,确保拦截正确

被测代码若通过from github import Github导入类,测试中需mock被测模块内的Github引用,而非原始类路径。比如被测模块为git_commons,则mock路径应为git_commons.Github。

示例代码:

from unittest.mock import patch, MagicMock
import pytest
from git_commons import GitCommons

def test_read_template_from_git():
    # 正确mock被测模块中的Github类
    with patch('git_commons.Github') as mock_github:
        # 配置mock返回的仓库与内容
        mock_repo = MagicMock()
        mock_file = MagicMock()
        mock_file.decoded_content = b'template content'
        mock_repo.get_contents.return_value = mock_file
        mock_github.return_value.get_repo.return_value = mock_repo

        # 执行被测逻辑
        gc = GitCommons()
        result = gc.read_template_from_git()

        # 断言验证
        mock_github.assert_called_once_with('12121212')  # 传入字符串类型token
        assert result == 'template content'

2. 修正Token类型,返回字符串

确保mock获取git_token的逻辑返回字符串类型,若通过boto3获取token,需mock对应方法返回字符串:

@pytest.fixture
def mock_boto3_session():
    with patch('boto3.session.Session') as mock_session:
        mock_client = MagicMock()
        # 返回字符串类型的token
        mock_client.get_parameter.return_value = {'Parameter': {'Value': '12121212'}}
        mock_session.return_value.client.return_value = mock_client
        yield mock_session

3. 调整导入时机,保证Mock优先加载

若测试在mock前导入了git_commons,真实Github类会提前加载导致mock失效,可通过以下方式解决:

  • 在测试函数内部导入被测模块
  • 使用patch装饰器,确保mock在模块导入前生效

示例(装饰器形式):

@patch('git_commons.Github')
@patch('boto3.session.Session')
def test_read_template_from_git(mock_session, mock_github):
    # 配置mock
    mock_client = MagicMock()
    mock_client.get_parameter.return_value = {'Parameter': {'Value': '12121212'}}
    mock_session.return_value.client.return_value = mock_client

    mock_repo = MagicMock()
    mock_file = MagicMock()
    mock_file.decoded_content = b'template content'
    mock_repo.get_contents.return_value = mock_file
    mock_github.return_value.get_repo.return_value = mock_repo

    # 延迟导入被测模块,确保mock已生效
    from git_commons import GitCommons
    gc = GitCommons()
    result = gc.read_template_from_git()

    assert result == 'template content'

4. 修复Fixture依赖问题

使用autouse fixture确保mock在所有测试前自动激活,避免依赖配置错误:

@pytest.fixture(autouse=True)
def mock_all():
    with patch('git_commons.Github') as mock_github, patch('boto3.session.Session') as mock_session:
        # 配置boto3 mock
        mock_client = MagicMock()
        mock_client.get_parameter.return_value = {'Parameter': {'Value': '12121212'}}
        mock_session.return_value.client.return_value = mock_client

        # 配置Github mock
        mock_repo = MagicMock()
        mock_file = MagicMock()
        mock_file.decoded_content = b'template content'
        mock_repo.get_contents.return_value = mock_file
        mock_github.return_value.get_repo.return_value = mock_repo

        yield

关键注意事项

  • Mock路径必须匹配被测代码中实际引用的类路径,这是Python mock生效的核心
  • 严格保证传入参数类型符合被mock类的要求,比如Github的token必须为字符串
  • 被测模块的导入时机必须晚于mock的初始化,否则真实类会提前加载导致mock失效

内容的提问来源于stack exchange,提问作者Srini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:24:58