Python模拟类属性无法访问

3

在模拟一个类对象时,我无法访问它的属性。 我已经阅读了很多文档,但我对模拟还很陌生,看不出这段代码的问题所在。我期望x和y返回相同的值1e-15。

class test_user_data:
    scale = 1e-15

class test_signal(unittest.TestCase):
    @patch('xx.user_data', autospec=test_user_data, spec_set=True)
    def test_data(self, mock_user_data):
        x = xx.user_data()
        y = test_user_data()
        print(x.scale)
        print(y.scale)

但是我得到了

<NonCallableMagicMock name='user_data().timescale' spec_set='float' id='47213638195072'>
1e-15
1个回答

1

autospec和spec的使用通常用于定义API。当使用Mock时,您几乎可以调用或访问它上面的任何属性,它都会允许您这样做。但是它会返回另一个mock对象。

看到像这样的东西:

>>> my_mock = Mock()
>>> my_mock.stuff
<Mock name='mock.stuff' id='139870989908344'>
>>> my_mock.junk()
<Mock name='mock.junk()' id='139870987197912'>

如果我定义了一个规范,它会告诉你不能访问实际类中不存在的东西。像这样:

>>> my_mock = Mock(spec=xx.user_data)
>>> my_mock.stuff
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.4/unittest/mock.py", line 574, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'stuff'
>>> my_mock.scale
<Mock name='mock.scale' id='139871128095264'>

上面的代码显示,如果在实际的“user_data”类中没有定义Mock中的属性,则无法访问它,因为我已经使用了spec。
这解释了autospec的工作原理,但实际上你需要的是“return_value”参数。请将其添加到您的修补程序装饰器中,然后您就可以开始了。它应该像这样:
@patch('xx.user_data', autospec=test_user_data, spec_set=True, return_value=test_user_data)

谢谢您的解释,您的解决方案解决了问题。如果test_user_data有一个__init__方法,是否有办法强制mock运行它? - Damo
1
我认为需要一些技巧才能得到你想要的结果,但我确信这是可能的。你试图通过这个做什么?你真的想测试__init__吗?还是你希望在模拟对象上发生__init__的效果?我鼓励你在这里看一下.side_effect: https://docs.python.org/3/library/unittest.mock.html#quick-guide 它将允许你分配函数指针(在这种情况下是指向原始__init__的函数指针),并可能实现你正在寻找的内容。 - wholevinski
@Damo 鉴于问题的复杂性,如果上面的链接并不能完全解决它,你可能需要考虑再开一个新的问题。 - wholevinski
1
感谢@wholevinski。您的回复解决了基本user_data的问题。我还有更复杂的user_data,其中包含其他字段和它们之间的依赖关系,这些字段在__init__中初始化。使用side_effect可以解决问题。具体方法如下:@patch('xx.user_data', autospec=test_user_data, return_value=test_user_data, side_effect=test_user_data.__init__(test_user_data)) - Damo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接