无法正确修补对象的属性

Unable to patch an object's attribute correctly

我有一个 Python 模块如下:

# src/exec.py

class A:

    def run(self, stuff):
        b = B(stuff.x)

class B:
    def __init__(self, x):
        self.obj = self.create_some_obj()

我正在尝试独立测试 class A 的一部分,为此我需要用假对象替换 B 中的 obj。我这样做如下:

# test/test_execs.py

import exec as ex

class FakeObjForB:
    def __init__(self):
        # some init

class TestClass:

    @patch.object(ex.B, 'obj', FakeObjForB())
    def test_with_fake_obj(self):
        a = ex.A()
        a.run()
        # assert something about the state of a that depends on the b inside its run method

运行 这个测试给我错误:AttributeError: <class 'B'> does not have the attribute 'obj'。我尝试用 @patch.object(ex.B, 'obj', FakeObjForB(), create=True) 替换带有 @patch 装饰器的行。然而,这导致 b.obj 使用实际定义,而不是 FakeObjForB,这反过来导致 test_with_fake_obj 中的断言错误失败。关于我在这里做错了什么的任何线索?

在您的示例中,您正在修补 B class,这是作为第一个参数传递的对象。 class 没有在 class 级别上声明 obj 属性,因此引发了 AttributeError。当您提供 create=True 时,它不会抱怨,因为该参数允许在 needed/accessed 时动态创建 obj 属性。但是,这永远不会发生,因为该属性的第一个 "access" 是它的实际创建 - 从未发生过动态模拟。

一个解决方案是实际修补其返回值将分配给 obj 属性的方法,例如:

@patch.object(ex.B, 'create_some_obj', FakeObjForB())