You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 03:39:34