如何用MagicMock模拟packet并测试capture_tstamp赋值正确性?
问题与解决方案
场景与代码
你有如下on_packet()相关业务代码:
class PacketContext: def __init__(self, capture_tstamp=None): self.capture_tstamp = capture_tstamp class Subparser(): def __init__(self): self.subparsers = {} self.context = PacketContext() def parse_er_data(self, bytes_data): parent_file_name = os.path.basename(self.filename or '') # 其他未展示的逻辑 .... def on_packet(self, packet): self.context.capture_tstamp = packet.capture_timestamp self.parse_er_data(packet.payload)
想要用MagicMock模拟packet对象,验证self.context.capture_tstamp是否被正确赋值,测试代码如下:
class TestTSE(Subparser, ExchangeTest): name = 'TSE' data_group = 'equities' default_subparser = TSEparser def __init__(self, *argv, **kwargs): Subparser.__init__(self) ExchangeTest.__init__(self, *argv, **kwargs) def test_receive_timestamp(self): packet = MagicMock(capture_timestamp=123456) self.on_packet(packet) assert self.context.capture_tstamp == 123456
报错原因
运行测试时触发AttributeError,因为调用on_packet后,方法会自动执行parse_er_data,而该方法依赖self.filename属性,但测试类TestTSE未初始化这个属性,导致报错。我们的测试目标只是验证capture_tstamp的赋值,无需执行parse_er_data的完整逻辑。
解决方法
方法1:Mock掉parse_er_data方法
直接在测试中替换parse_er_data为Mock对象,跳过真实逻辑执行:
def test_receive_timestamp(self): packet = MagicMock(capture_timestamp=123456) # 替换parse_er_data,避免执行真实逻辑 self.parse_er_data = MagicMock() self.on_packet(packet) assert self.context.capture_tstamp == 123456
方法2:给测试实例添加filename属性
如果需要保留parse_er_data的执行,可直接在测试中初始化filename:
def test_receive_timestamp(self): packet = MagicMock(capture_timestamp=123456) # 给当前测试实例添加filename属性 self.filename = "test_sample.txt" self.on_packet(packet) assert self.context.capture_tstamp == 123456
也可以在测试类的__init__中统一初始化:
def __init__(self, *argv, **kwargs): Subparser.__init__(self) ExchangeTest.__init__(self, *argv, **kwargs) self.filename = "" # 初始化filename属性
方法3:用patch临时替换方法
使用patch装饰器临时替换parse_er_data,适合多测试复用的场景:
from unittest.mock import patch def test_receive_timestamp(self): packet = MagicMock(capture_timestamp=123456) with patch.object(self, 'parse_er_data'): self.on_packet(packet) assert self.context.capture_tstamp == 123456
方法4:创建独立Subparser实例测试(推荐)
避免测试类继承带来的干扰,直接创建Subparser的独立实例进行测试:
def test_receive_timestamp(self): # 创建独立的Subparser实例,隔离测试环境 subparser = Subparser() packet = MagicMock(capture_timestamp=123456) # Mock掉parse_er_data subparser.parse_er_data = MagicMock() subparser.on_packet(packet) assert subparser.context.capture_tstamp == 123456
内容的提问来源于stack exchange,提问作者Patrick_Chong
相关产品推荐
相关产品推荐

