【问题标题】:Mocking Class Functions模拟类函数
【发布时间】:2018-09-11 23:16:32
【问题描述】:

我正在尝试对一个具有相当复杂的 __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?

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

【问题讨论】:

    标签: python mocking python-unittest


    【解决方案1】:

    我认为您无法通过 MagicMock 实现这一目标。

    一种方法是使用__new__ 类方法来创建类的实例而不调用其__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__() 会很有帮助。

    【讨论】:

    • 那么就没有办法给Mock对象添加方法了吗?
    • 你可以,但上述方法会大大减少头痛
    【解决方案2】:

    您可以只删除类而不是模拟。

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

    【讨论】:

      猜你喜欢
      • 2019-03-22
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多