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

测试else分支中调用的get_sync_column函数断言失败问题排查

问题:Mock断言失败且else分支未覆盖的解决方法

我编写了一段代码,在cal_sync_column方法的else分支中调用返回字符串的get_sync_column函数。对该函数Mock后断言它被调用一次,但断言失败,同时代码覆盖率因else分支里的get_sync_column()未被覆盖而下降。

原函数

from dataclasses import dataclass, ClassVar

@dataclass(frozen=True)
class RMTable():
    sync_column: ClassVar[str] = None

    def __post_init__(self) -> None:
        if self.sync_column is None:
            object.__setattr__(self, "sync_column", self.cal_sync_column())

    def cal_sync_column(self) -> str:
        if not feature_flag():
            return "_synced"
        else:
            return get_sync_column() # returns str

测试函数

from unittest.mock import patch, MagicMock

def test_sync_column():
     with patch("my_module.feature_flag") as feature_flag_mock:
         with patch("my_module.get_sync_column") as mock_sync_column:
             feature_flag_mock.return_value = True
             rm_table_mock = MagicMock(spec=RMTable)
             rm_table_mock.cal_sync_column.return_value = "FLAG_1"
             result = rm_table_mock.cal_sync_column()
             assert result == "FLAG_1"
             mock_sync_column.assert_called_once()

错误信息

AssertionError: Expected 'get_sync_column' to have been called once. Called 0 times.

问题原因

你用MagicMock(spec=RMTable)创建了RMTable的Mock对象,并且直接给rm_table_mock.cal_sync_column.return_value赋值为"FLAG_1"。这导致调用rm_table_mock.cal_sync_column()时,执行的是Mock的预设返回值,完全没有触发真实的cal_sync_column方法逻辑,自然不会走到else分支调用get_sync_column,所以断言失败,同时真实代码的else分支也没被覆盖。

修正方案

要测试真实的cal_sync_column逻辑,应该实例化真实的RMTable对象,仅Mockfeature_flag和get_sync_column这两个外部依赖:

修正后的测试代码

from unittest.mock import patch

def test_sync_column():
    with patch("my_module.feature_flag") as feature_flag_mock:
        with patch("my_module.get_sync_column") as mock_sync_column:
            # 设置feature_flag返回True,触发else分支
            feature_flag_mock.return_value = True
            # 预设get_sync_column的返回值
            mock_sync_column.return_value = "FLAG_1"
            
            # 实例化真实的RMTable对象
            rm_table = RMTable()
            # 调用真实的cal_sync_column方法
            result = rm_table.cal_sync_column()
            
            assert result == "FLAG_1"
            mock_sync_column.assert_called_once()

额外测试__post_init__逻辑

如果要验证__post_init__中自动调用cal_sync_column设置sync_column的逻辑,可以直接实例化对象后断言属性值:

from unittest.mock import patch

def test_post_init_sync_column():
    with patch("my_module.feature_flag") as feature_flag_mock:
        with patch("my_module.get_sync_column") as mock_sync_column:
            feature_flag_mock.return_value = True
            mock_sync_column.return_value = "FLAG_1"
            
            rm_table = RMTable()
            # 断言sync_column被正确初始化
            assert rm_table.sync_column == "FLAG_1"
            mock_sync_column.assert_called_once()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:37:44