(对于那些对一个模拟返回不同的不同值感到好奇的人,请参阅我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 时,您是正确的-但是,使用 的语句,Pythona, b = foo()
期望找到一个元组,并且在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
。