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

如何断言unittest Mock仅存在指定调用且无其他调用?

如何断言Mock仅被指定调用触发?

Mock.assert_has_calls仅断言指定调用存在,但无法保证这些是仅有的调用:

from unittest.mock import Mock, call

mock = Mock()

mock("foo")
mock("bar")
mock("baz")

mock.assert_has_calls([call("foo"), call("bar")])  # 此断言会通过

如何断言mock仅被调用了foo和bar,没有其他调用?

我曾尝试用集合实现,但call是不可哈希的:

assert set(mock.mock_calls) == {call("foo"), call("bar")}

可行解决方案

1. 直接对比完整调用列表

mock.mock_calls会按调用顺序保存所有调用记录,直接断言列表完全匹配即可:

assert mock.mock_calls == [call("foo"), call("bar")]

如果不关心调用顺序,可先对列表排序后再对比:

assert sorted(mock.mock_calls) == sorted([call("foo"), call("bar")])

2. 自定义辅助函数处理无顺序断言

如果需要忽略调用顺序且不想排序,可以把call对象转换为可哈希的结构(比如元组),再用集合对比:

def assert_mock_only_has_calls(mock, expected_calls):
    # 提取调用的参数和关键字参数,转为可哈希元组
    actual_calls = tuple((args, kwargs) for _, args, kwargs in mock.mock_calls)
    expected_calls_tuple = tuple((args, kwargs) for _, args, kwargs in expected_calls)
    assert set(actual_calls) == set(expected_calls_tuple), \
        f"预期调用: {expected_calls}, 实际调用: {mock.mock_calls}"

# 使用示例
assert_mock_only_has_calls(mock, [call("foo"), call("bar")])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:57:06