模拟 Class 函数

Mocking Class Functions

我正在尝试对一个 class 进行单元测试,它有一个相当复杂的 __init__,一个涉及对服务器和外部组件的调用。我发现你可以使用 unittest MagicMock 来伪造一个 init。

class my_class:
    def __init__(self, arg1, arg2):
        self.var = arg1
        self.method1(arg2)

    def method1(self, arg):
        var = "Hello " + arg
        self.method2(var)

    def method2(self, var):
        print(var)

SELF = MagicMock()
my_calss.my_class.__init__(SELF, arg1, arg2)

太棒了,因为所有与服务器通信的代码都在其他方法中,我可以确保 __init__ 调用某些方法。

当我想测试一个调用另一个方法的方法时,问题就来了。

SELF = MagicMock()
my_class.__init__(SELF, arg1, arg2)
SELF.method2 = my_class.method2
my_class.method1(SELF, arg)

我希望 method2 中的 self 是 SELF,但 method2 永远不会得到 self。 有没有办法确保 method2 获得模拟的 SELF?

或者另一种测试方法 class 不涉及大量补丁的方法?

我认为 MagicMock 无法实现。

一种方法是使用 __new__ class 方法创建 class 的实例而不调用它的 __init__ 方法,然后在根据需要测试设置。

例如

instance = my_class.__new__(my_class)
# Manually initialize properties as needed.
instance.usually_set_by_init = 3

# Use the instance like normal.
instance.method1(arg)

如果您还没有听说过 __new__,这可能看起来很奇怪,但了解 a = A() 等同于 a = A.__new__(A); a.__init__() 是很有帮助的。

您可以直接删除 class 而不是模拟。

class MyClassStub(MyClass): def __init__(self): pass # bypass parents init