Python3.6以下版本如何实现Mock().assert_called_once类似功能?
如何在Python 3.6以下版本验证Mock方法被恰好调用一次(忽略参数)
在Python 3.6之前,unittest.mock.Mock确实没有提供assert_called_once()这个便捷方法——它是Python 3.6才新增的特性。如果你需要验证某个mock方法被恰好调用一次,同时完全不关心调用时传入的参数类型、数量,那用assert_called_once_with()配合unittest.mock.ANY确实没法直接满足需求,因为ANY要求你必须匹配参数的个数,没法做到彻底忽略参数。
这里有两个简单可靠的解决方案:
方案1:直接检查call_count属性
最直接的方式就是利用mock对象自带的call_count属性,结合单元测试框架的assertEqual来验证调用次数:
from unittest import mock, TestCase class ExampleTest(TestCase): def test_target_method_called_once(self): # 创建mock对象 target_mock = mock.Mock() # 模拟业务逻辑中的调用(参数随便传,不影响验证) target_mock("foo", bar=123, extra="whatever") # 验证调用次数恰好为1 self.assertEqual(target_mock.call_count, 1)
这种方式完全不涉及参数检查,只关注调用次数,正好符合你的需求。
方案2:自定义断言方法
如果你更习惯用类似assert_called_once()的方法调用形式,可以自己封装一个简单的辅助函数:
from unittest.mock import Mock def assert_called_once(mock_obj: Mock): if mock_obj.call_count != 1: raise AssertionError(f"Expected mock to be called once, but it was called {mock_obj.call_count} times") # 使用示例 my_mock = Mock() my_mock() # 调用一次 assert_called_once(my_mock) # 断言通过 my_mock() # 再调用一次 assert_called_once(my_mock) # 抛出AssertionError
为什么unittest.mock.ANY不适用?
你之前尝试的ANY,本质是参数匹配器,它要求你必须和实际调用的参数数量一一对应。比如如果你的方法被调用时传了2个位置参数,你得写mock.assert_called_once_with(ANY, ANY);如果是关键字参数,还要对应键名。但如果参数数量不确定,或者你完全不想关注参数,这种方式就非常繁琐,甚至无法实现——而检查call_count就完美解决了这个问题。
内容的提问来源于stack exchange,提问作者Ahasanul Haque
相关产品推荐
相关产品推荐

