我正在尝试模拟一个库(matplotlib
的价值),并且遇到一个问题,即在调用该模拟并期望返回一个元组时,它会失败。有更好的方法吗?
Python 3.7.2 (default, Jan 13 2019, 12:50:15)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 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)
>>>
答案 0 :(得分:0)
您可以使用选择的元组设置return_value
对象的MagicMock
属性:
import mock
foo = mock.MagicMock()
foo.return_value = 1, 2
a, b = foo()
assert a == 1
assert b == 2
答案 1 :(得分: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
)让我们探索其中的一些可能性。< /p>
当 you mentioned MagicMock
总是为其调用的任何内容返回 MagicMock
时,您是正确的 - 但是,使用 a, b = foo()
语句,Python 期望找到一个元组,并且在 MagicMock
可以创建默认的单个 MagicMock
返回值之前触发错误,因此错误表明它找到了要使用的 0
值。
您创建 MagicMock
元组的解决方案可以有多种不同的方式 - 从您的问题中不清楚使用 a, b =
分配值是否对您更重要。如果是,那么你可以这样做:
import mock
foo = mock.MagicMock()
a, b = (mock.MagicMock(), mock.MagicMock())
或者这个:
a, b = (foo(), foo())
或者,如果您对让一个函数调用为您填充这些值更感兴趣,as mentioned,您可以像这样分配一个 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()
对于那些对 this comment 感到好奇的人,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
。