首页 > 解决方案 > 部分模拟 Python 类 __init__?

问题描述

我有一个具有复杂初始化的 Python 类。我想模拟类初始化以避免编写过多的脚手架代码。我想测试它的非模拟方法。

一个简单的例子:

class Person:

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def do_work(self):
        return self.x + self.y

有一个答案显示了如何完成它并且它有效 - https://stackoverflow.com/a/21771920/3346915

这是一个通过测试:

from unittest.mock import patch
with patch.object(Person, '__init__', lambda self: None):
    person = Person()
    person.x = 3
    person.y = 4
    assert person.do_work() == 7

但是,我想知道是否可以通过xy作为Person初始化的一部分来避免在构造后分配字段以减少代码量?

我想知道这是否可能?

from unittest.mock import patch
with patch.object(Person, '__init__', lambda self, x, y: None):
    person = Person(x=3, y=4)
    assert person.do_work() == 7

这当然不起作用,因为xandy值没有分配给person实例。

标签: pythonunit-testingmockingpython-unittestpatch

解决方案


lambdas 不支持赋值,但你不必使用lambda作为第三个参数 - 普通(命名)函数也可以,所以你可以这样做:

class Person:

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def do_work(self):
        return self.x + self.y

from unittest.mock import patch
def newinit(self, x, y):
    self.x = x
    self.y = y
with patch.object(Person, '__init__', newinit):
    person = Person(x=3, y=4)
    assert person.do_work() == 7

(在 Python 3.7.3 中测试)


推荐阅读