在不运行__init__的情况下测试实例方法的最佳方式

7 投票
2 回答
2284 浏览
提问于 2025-04-15 22:51

我有一个简单的类,它大部分参数都是通过初始化方法(init)传入的,同时这个初始化方法还会调用一些私有方法来完成大部分工作。输出结果可以通过访问对象的变量或者公共方法来获取。

现在的问题是,我希望我的单元测试框架能够直接调用这些在初始化方法中被调用的私有方法,并且使用不同的数据,而不需要经过初始化方法。

这样做的最佳方法是什么呢?

到目前为止,我一直在重构这些类,让初始化方法做的事情少一些,数据单独传入。这样测试起来比较简单,但我觉得类的可用性可能会受到一些影响。

编辑:根据Ignacio的回答,给出的一个示例解决方案:

import types

class C(object):

   def __init__(self, number):
       new_number = self._foo(number)
       self._bar(new_number)

   def _foo(self, number):
       return number * 2

   def _bar(self, number):
       print number * 10

#--- normal execution - should print 160: -------
MyC = C(8)

#--- testing execution - should print 80 --------
MyC = object.__new__(C)
MyC._bar(8)

2 个回答

4

为什么这个类的可用性要受到影响呢?如果所有的 __init__ 方法只是为了提前计算一些东西,以便你可以把这些值作为简单的变量来使用,那你可以把这些变量改成 属性,然后在获取这些属性的时候再进行计算(可以考虑缓存或者记忆化)。这样一来,你的 __init__ 方法就只负责初始化了,测试起来也会更方便。

不过,这种做法的一个缺点是,它 可能 性能会稍微差一些,但大概不会差得太多。

6

对于新式类,你需要调用 object.__new__(),并把类作为参数传进去。对于旧式类,你则需要调用 types.InstanceType(),同样把类作为参数传进去。

import types

class C(object):
  def __init__(self):
    print 'init'

class OldC:
  def __init__(self):
    print 'initOld'

c = object.__new__(C)
print c

oc = types.InstanceType(OldC)
print oc

撰写回答