如何编写单元测试验证Child类send方法被调用而非Parent且message正确?
单元测试实现方案
当然可以编写这样的单元测试,下面是具体实现方法,重点解决你关于patch/mock的困惑:
测试目标拆解
我们需要验证两个核心点:
- 调用的是
Child类的send方法(而非直接调用Parent的send) - 调用
send时,实例的self.message等于指定值
测试代码实现
import unittest from unittest.mock import patch from module_b import some_function from module_a import Child, Parent class TestSomeFunction(unittest.TestCase): def test_child_send_called_with_correct_message(self): # 1. Patch父类Parent的send方法,用于排查是否被调用 with patch.object(Parent, 'send') as mock_parent_send: # 2. 临时替换Child的send方法,加入断言逻辑 original_child_send = Child.send def checked_send(self): # 验证当前实例的message是否符合预期 self.assertEqual(self.message, 'Some Message Here') # 保留原send方法的执行逻辑(不需要的话可以删除此行) original_child_send(self) Child.send = checked_send try: # 执行待测试的函数 some_function() # 验证父类的send从未被直接调用 mock_parent_send.assert_not_called() finally: # 恢复Child的原send方法,避免影响其他测试用例 Child.send = original_child_send if __name__ == '__main__': unittest.main()
关键步骤说明
验证父类方法未被调用:
用patch.object(Parent, 'send')把父类的send替换为Mock对象,测试结束后通过assert_not_called()确认父类方法没有被直接触发,保证调用的是Child类绑定的方法(即使它继承自父类)。验证self.message的值:
临时替换Child.send为自定义的checked_send方法,在方法内部直接对self.message做断言,这样就能在send执行的上下文里验证实例属性的正确性。
更简洁的Mock写法(无需保留原逻辑)
如果不需要保留send方法的原打印逻辑,可以直接MockChild.send并捕获调用时的实例:
def test_child_send_simplified(self): with patch.object(Child, 'send') as mock_child_send: some_function() # 确认Child的send方法被调用了一次 self.assertEqual(mock_child_send.call_count, 1) # 获取调用send时的Child实例(call_args[0][0]就是self参数) child_instance = mock_child_send.call_args[0][0] # 验证实例的message属性值 self.assertEqual(child_instance.message, 'Some Message Here') # 可选:验证Child的send确实继承自Parent(如果需要确认这一点) self.assertIs(Child.send, Parent.send)
关于patch的核心用法总结
patch.object(target, attr):专门用于替换某个对象(比如类)的指定属性/方法,用with语句包裹时会自动在代码块结束后恢复原属性,避免测试污染。- Mock对象的
call_args属性:可以获取方法调用时的参数列表,第一个位置的参数就是实例本身(self),通过它能访问实例的所有属性。
内容的提问来源于stack exchange,提问作者GhostKU
相关产品推荐
相关产品推荐

