模拟:跟踪所有调用,Shell与程序不一致
为什么在命令行中运行和在程序中运行时,mock.mock_calls
的内容会不一样呢?当我在程序中检查mock.mock_calls == expected
时,它会失败,但在命令行中却能通过。这段代码是根据文档中的示例来追踪多个调用的。(26.5.1.5. 追踪所有调用)
>>> from unittest.mock import MagicMock, call
>>> mock = MagicMock()
>>> mock.method()
<MagicMock name='mock.method()' id='57725952'>
>>> mock.attribute.method(10, x=53)
<MagicMock name='mock.attribute.method()' id='57775944'>
>>> mock.mock_calls
[call.method(), call.attribute.method(10, x=53)]
>>> mock.method_calls
[call.method(), call.attribute.method(10, x=53)]
>>> expected = [call.method(), call.attribute.method(10, x=53)]
>>> expected == mock.mock_calls
True
>>> expected == mock.method_calls
True
到目前为止,这一切都和预期的一样。但看看在程序中mock.mock_calls
发生了什么:它记录了每个被调用方法的__str__
方法的额外调用。而mock.method_calls
没有受到影响。
import unittest.mock
mock = unittest.mock.MagicMock()
print(mock.method())
print(mock.attribute.method(10, x=53))
print('\nmock.mock_calls\n', mock.mock_calls)
print('\nmock.method_calls\n', mock.method_calls)
expected = [unittest.mock.call.method(),
unittest.mock.call.attribute.method(10, x=53)]
print(expected == mock.mock_calls)
print(expected == mock.method_calls)
输出:
<MagicMock name='mock.method()' id='45740272'>
<MagicMock name='mock.attribute.method()' id='45850128'>
mock.mock_calls
[call.method(),
call.method().__str__(),
call.attribute.method(10, x=53),
call.attribute.method().__str__()]
mock.method_calls
[call.method(), call.attribute.method(10, x=53)]
False
True
我在Windows 7的电脑上运行Python 3.4。
1 个回答
2
这是因为你在打印方法调用。这会导致调用一个叫做 __str__()
的特殊方法:
print(mock.method())
print(mock.attribute.method(10, x=53))
去掉 print()
的调用,你就会看到想要的效果:
mock.method()
mock.attribute.method(10, x=53)
顺便说一下,这是控制台中的一个例子:
>>> mock = unittest.mock.MagicMock()
>>> print(mock.method())
<MagicMock name='mock.method()' id='4433183576'>
>>> print(mock.attribute.method(10, x=53))
<MagicMock name='mock.attribute.method()' id='4433223752'>
>>> mock.mock_calls
[call.method(),
call.method().__str__(),
call.attribute.method(10, x=53),
call.attribute.method().__str__()]
或者,你也可以使用一个普通的 Mock
类:
>>> mock = unittest.mock.Mock()
>>> print(mock.method())
<Mock name='mock.method()' id='4433235528'>
>>> print(mock.attribute.method(10, x=53))
<Mock name='mock.attribute.method()' id='4433252648'>
>>> mock.method_calls
[call.method(), call.attribute.method(10, x=53)]
>>> mock.mock_calls
[call.method(), call.attribute.method(10, x=53)]