Python 返回 MagicMock 对象而不是 return_value

Posted

技术标签:

【中文标题】Python 返回 MagicMock 对象而不是 return_value【英文标题】:Python returns MagicMock object instead of return_value 【发布时间】:2016-11-07 00:42:29 【问题描述】:

我有一个 Python 文件 a.py,其中包含两个类 AB

class A(object):
    def method_a(self):
        return "Class A method a"

class B(object):
    def method_b(self):
        a = A()
        print a.method_a()

我想通过模拟A 在课堂B 中对method_b 进行单元测试。以下是用于此目的的文件testa.py 的内容:

import unittest
import mock
import a


class TestB(unittest.TestCase):

    @mock.patch('a.A')
    def test_method_b(self, mock_a):
        mock_a.method_a.return_value = 'Mocked A'
        b = a.B()
        b.method_b()


if __name__ == '__main__':
    unittest.main()

我希望在输出中得到Mocked A。但我得到的是:

<MagicMock name='A().method_a()' id='4326621392'>

我哪里做错了?

【问题讨论】:

测试时,A()mock_A 返回return_value(一个普通的MagicMock,因为您没有指定其他任何内容),它不是@987654336 类的实例@。您需要将 return_value 设置为具有已定义 method_a 的内容。 mock_a.method_a.return_value = 'Mocked A' => mock_a().method_a.return_value = 'Mocked A' 应该更好:) @AliSAIDOMAR 是完全正确的,应该是调用mock_a 的返回值,而不是mock_a 本身。 @jonrsharpe 。谢谢你的解释。我刚试过。 mock_a().method_a.return_value = 'Mocked A'mock_a.return_value.method_a.return_value = 'Mocked A' 都有效。非常感谢您的 cmets。请你继续把它作为答案吗? @MehdiJafarniaJahromi 非常感谢! 【参考方案1】:

当您@mock.patch('a.A') 时,您正在用mock_a 替换被测代码中的类A

然后在B.method_b 中设置a = A(),现在是a = mock_a() - 即amock_areturn_value。因为你没有指定这个值,所以它是一个普通的MagicMock;这也没有配置,所以在调用它的方法时你会得到默认响应(又一个MagicMock)。

相反,您想配置 return_valuemock_a 以具有适当的方法,您可以这样做:

mock_a().method_a.return_value = 'Mocked A' 
    # ^ note parentheses

或者,也许更明确地说:

mock_a.return_value.method_a.return_value = 'Mocked A'

您的代码可以在 a = A 的情况下工作(分配类,而不是创建实例),因为那时 a.method_a() 会触发您的模拟方法。

【讨论】:

太棒了。你让我开心。 嗨@jonrsharpe,我正在使用带有 df.columns 的 pandas 数据框来检查我的 if 条件。它不使用括号(即,它不可调用)。在这种情况下,我该怎么做才能返回列表。谢谢! @imsrgadich 你需要一个 mock 吗?只需构建适当的数据框,将其视为测试值。 @jonrsharpe 是的,我可以这样做,但我也在我需要断言的被调用方法中执行 df.drop,并且我不会从被调用方法返回数据帧。这就产生了一个问题。我找到了一种使用mock_data.configure_mock(columns='my_column') 的方法来解决它。感谢您的回复。 (参考:bradmontgomery.net/blog/how-world-do-you-mock-name-attribute) 这个解释比任何 python 文档都好。谢谢!

以上是关于Python 返回 MagicMock 对象而不是 return_value的主要内容,如果未能解决你的问题,请参考以下文章

Python 3:unittest.mock如何为特定输入指定不同的返回值?

Python MagicMock在使用装饰器时嘲弄太多

如何在 Python MagicMock 中模拟 Azure ServiceBus 接收器

magicmock多次调用,但我无法断言调用

python django ajax:ValueError:视图没有返回 HttpResponse 对象。它返回 None 而不是

使用 SWIG 将 C++ 对象指针传递给 Python,而不是再次返回 C++