如何使用@patch模拟类的属性?Eobi类partitions属性模拟失败问题求助
解决Python Mock属性模拟的问题
看起来你在模拟类属性的时候踩了几个常见的坑,我来帮你梳理一下问题和解决办法:
核心问题分析
- 错误的Mock类型:你用了普通的
mock.patch加return_value来模拟属性,但partitions是实例属性而非方法,普通Mock无法正确模拟属性的访问行为,需要用PropertyMock。 - Mock目标不匹配:你的生产代码中是
self.partitions[pkthdr.partitionid].channels[packet.header.dst_ip],你需要的不是partitions直接返回100,而是构建一个嵌套的结构,让链式访问最终得到100。 - 可能的路径错误:你定义的类是
Eobi,但patch的是EobiExchange,要确保patch的路径和生产代码中实际引用的类完全一致。
修正后的测试代码示例
from unittest import mock # 注意:替换成你实际需要patch的类路径,确保和生产代码中check_for_sequence_reset所在类的partitions属性路径一致 @mock.patch('exchanges.protocols.eobi.parser.Eobi.partitions', new_callable=mock.PropertyMock) def test_check_for_sequence_reset(mock_partitions, xwbo_exchange, test, result): # 1. 构建最终要返回的channel对象,这里直接设置为100满足你的需求 channel_mock = 100 # 如果后续代码需要访问channel的属性(比如next_seqno),则改用Mock对象: # channel_mock = mock.Mock() # channel_mock.next_seqno = 0 # 根据测试场景设置对应值 # 2. 构建channels字典,key对应测试用例中packet.header.dst_ip的值 test_dst_ip = test["packet_header_dst_ip"] # 假设你的test数据包含该字段 channels_mock = {test_dst_ip: channel_mock} # 3. 构建partition对象,包含channels属性 partition_mock = mock.Mock() partition_mock.channels = channels_mock # 4. 构建partitions字典,key对应测试用例中pkthdr.partitionid的值 test_partition_id = test["pkthdr_partitionid"] # 假设你的test数据包含该字段 mock_partitions.return_value = {test_partition_id: partition_mock} # 执行测试逻辑 packet = test["packet"] pkthdr = test["pkthdr"] partition = test["partition"] actual_result = xwbo_exchange.check_for_sequence_reset(packet, pkthdr, partition) # 断言测试结果 assert actual_result == result
关键说明
- 用PropertyMock模拟属性:
new_callable=mock.PropertyMock告诉patch我们要模拟的是一个属性而非方法,这样代码中访问self.partitions时会正确返回预设的mock结构。 - 构建嵌套Mock结构:因为生产代码是链式索引访问,必须逐层构建对应的字典或Mock对象,保证每一层的索引都能拿到下一层的目标值。
- 路径正确性:patch的路径必须是生产代码中实际使用该属性的类的完整路径,比如如果
check_for_sequence_reset是Eobi类的方法,就patchEobi.partitions;如果是EobiExchange则对应调整。
简化写法提示
如果测试中不需要验证属性的调用细节,也可以直接返回嵌套字典替代Mock对象:
mock_partitions.return_value = { test_partition_id: { "channels": {test_dst_ip: 100} } }
这种写法更简洁,但如果后续需要断言channels的访问行为,还是用Mock对象更灵活。
内容的提问来源于stack exchange,提问作者Patrick_Chong
相关产品推荐
相关产品推荐

