如何模拟被测类的对象列表成员并断言对象方法被调用?
问题分析
你当前的测试代码用真实的Member实例填充MyClass.members,但真实实例的some_method未被Mock,因此无法通过assert_called()断言方法是否被调用。要实现断言,需对Member的some_method或实例本身做Mock处理。
解决方案
以下是两种可行的测试方案:
方案一:Mock每个Member实例的some_method
创建带Mock方法的模拟Member对象,替换MyClass.members后断言每个Mock方法的调用情况:
import unittest from unittest.mock import MagicMock from src.myclass import MyClass class MyClassTest(unittest.TestCase): def test_myclass_some_method(self): # 创建三个带Mock some_method的模拟Member对象 mock_member1 = MagicMock() mock_member2 = MagicMock() mock_member3 = MagicMock() # 替换MyClass的members类属性 MyClass.members = [mock_member1, mock_member2, mock_member3] # 调用MyClass的some_method MyClass.some_method(MyClass, 'four') # 断言每个member的some_method都被调用一次,参数正确 mock_member1.some_method.assert_called_once_with('four') mock_member2.some_method.assert_called_once_with('four') mock_member3.some_method.assert_called_once_with('four') if __name__ == "__main__": unittest.main()
方案二:Mock Member类的some_method方法
通过patch替换Member类的some_method为Mock方法,检查该方法的调用次数和参数:
import unittest from unittest.mock import patch from src.myclass import MyClass from src.member import Member class MyClassTest(unittest.TestCase): def test_myclass_some_method(self): # 替换Member类的some_method为Mock with patch.object(Member, 'some_method') as mock_some_method: # 初始化MyClass并填充members my_instance = MyClass('one', 'ten', 'eleven', 'thirteen') # 调用实例的some_method my_instance.some_method('four') # 断言some_method被调用3次(对应3个member) self.assertEqual(mock_some_method.call_count, 3) # 验证调用参数 mock_some_method.assert_any_call('four') if __name__ == "__main__": unittest.main()
额外说明
- 原代码中用类直接调用实例方法
MyClass.some_method并传入MyClass作为self参数,语法上可行,但更规范的做法是创建MyClass实例后调用实例方法。 - 方案一适合单独验证每个成员的调用细节,方案二更适合批量验证调用次数或通用参数。
内容的提问来源于stack exchange,提问作者Max OfLondon
相关产品推荐
相关产品推荐

