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

如何测试父类__init__方法是否被传入正确参数调用?

问题:验证子类调用父类构造方法时出现参数错误

我在为类B编写单元测试,要验证创建B实例时super().__init__是否被正确调用,写了如下代码:

import pytest

class A:
  def __init__(self, some_val, **kwargs):
    self.some_val = some_val


class B(A):
  def __init__(self, some_val, some_other_val, **kwargs):
    super().__init__(some_val, **kwargs)
    self.some_other_val = some_other_val


def test_example(mocker):
  def side_effect(self, some_val, **kwargs):
    original_init(self, some_val, **kwargs)

  original_init = A.__init__

  mocker.patch.object(A, "__init__", side_effect=side_effect)

  some_val = "abc"
  some_other_val = "xyz"

  instance = B(some_val, some_other_val)

  A.__init__.assert_called_once_with(instance, some_val)

运行时出现以下错误:

TypeError: test_example.<locals>.side_effect() missing 1 required positional argument: 'some_val'

解决方案

问题出在side_effect的参数处理和mock的使用方式上,修正后的代码如下:

import pytest

class A:
    def __init__(self, some_val, **kwargs):
        self.some_val = some_val

class B(A):
    def __init__(self, some_val, some_other_val, **kwargs):
        super().__init__(some_val, **kwargs)
        self.some_other_val = some_other_val

def test_example(mocker):
    # 提前保存原始的父类构造方法
    original_init = A.__init__
    # 用原始方法作为side_effect,既保留原逻辑又能记录调用
    mock_init = mocker.patch.object(A, "__init__", side_effect=original_init)

    some_val = "abc"
    some_other_val = "xyz"

    instance = B(some_val, some_other_val)

    # 断言父类构造方法被正确调用,注意包含空的关键字参数
    mock_init.assert_called_once_with(instance, some_val, **{})

关键修正点

  1. 简化side_effect:不需要手动包装side_effect函数,直接把原始的A.__init__传给side_effect即可,这样mock会自动处理参数传递,避免手动写函数时的参数匹配问题。
  2. 使用mock对象断言:保存patch返回的mock对象(mock_init),用它来做断言更可靠,避免直接操作A.__init__可能带来的混淆。
  3. 完整参数断言:父类构造方法调用时包含**kwargs(即使是空的),所以断言时要加上**{},确保参数完全匹配。

内容的提问来源于stack exchange,提问作者archjkeee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:37:20