如何使MagicMock返回多个值



我正在尝试模拟图书馆(matplotlib的价值),并且在称为"指望返回元组"时,它会遇到一个问题。有更好的方法吗?

Python 3.7.2 (default, Jan 13 2019, 12:50:15) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
>>> import mock
>>> foo = mock.MagicMock()
>>> a, b = foo()

这是收到的错误消息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: not enough values to unpack (expected 2, got 0)
>>> 

(对于那些对此感到好奇的人对一个模拟返回不同的值的人,请参见我在下面答案的末尾对side_effect的使用。)

我将从您的问题中的第一个语句开始:

我正在尝试模拟图书馆(matplotlib的价值)

如果您能够正确嘲笑此库,则不必担心任何子功能的行为 - 因为它们都会被嘲笑,并且您可以确定模拟的功能应如何表现。我如何通过使用patch实现类似行为 - 具体来说,patch.object应该有所帮助:

import mock
mock_matplotlib = mock.MagicMock()
mock_matplotlib.return_value = whatever_mock_behavior_you_want
with mock.patch.object(my_app, "matplotlib", mock_matplotlib):
    # Call the function you are testing which uses matplotlib

您现在可以自由地替换您想要的mock_matplotlib,以便它以您寻求的方式行为...(即mock_matplotlib.return_value = mock_tuple)让我们探索其中的一些可能性。

当您提到MagicMock总是返回MagicMock的任何内容时,您是正确的 - 但是,使用a, b = foo()的说明,Python期望找到一个元组,并且该错误在MagicMock可以创建默认的单个MagicMock之前触发了错误返回值,因此错误说它找到了可以使用的0值。

您创建MagicMock s元组的解决方案可能会有多种不同的方式 - 从您的问题中不清楚用a, b =分配值是否对您更重要。如果是这样,您可以这样做:

import mock
foo = mock.MagicMock()
a, b = (mock.MagicMock(), mock.MagicMock())

或以下:

a, b = (foo(), foo())

或,如果您对一个函数呼叫更感兴趣,请填写这些值,如上所述,您可以分配这样的return_value

foo = mock.MagicMock()
foo.return_value = (mock.MagicMock(), mock.MagicMock())
a, b = foo()

甚至喜欢这样:

foo = mock.MagicMock(return_value=(mock.MagicMock(), mock.MagicMock()))
a, b = foo()

对于那些对此评论感到好奇的人,OP是正确的,这与每次调用MagicMock时返回不同的值不同。这将使用side_effect选项 - 但是,即使是以回旋的方式来实现OP的目标:

mock_1 = mock.MagicMock()
mock_2 = mock.MagicMock()
foo = mock.MagicMock(side_effect=[mock_1, mock_2])
a, b = (foo(), foo())

在最后一个示例中,将mock_1分配给a,将mock_2分配给b

您可以用您选择的元组设置MagicMock对象的return_value属性:

import mock
foo = mock.MagicMock()
foo.return_value = 1, 2
a, b = foo()
assert a == 1
assert b == 2

相关内容

  • 没有找到相关文章

最新更新