Python Mock 与 MagicMock
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17181687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mock vs MagicMock
提问by Vladimir Ignatov
My understanding is that MagicMockis a superset of Mockthat automatically does "magic methods" thus seamlessly providing support for lists, iterations and so on... Then what is the reason for plain Mockexisting? Isn't that just a stripped down version of MagicMockthat can be practically ignored? Does Mockclass know any tricks that are not available in MagicMock?
我的理解是,MagicMock是Mock的超集,它会自动执行“魔术方法”,从而无缝地提供对列表、迭代等的支持……那么普通Mock存在的原因是什么?这不就是一个几乎可以忽略的精简版MagicMock吗?Mock类是否知道MagicMock中没有的任何技巧?
回答by Sean Redmond
With Mock you canmock magic methods but you have to define them. MagicMock has "default implementations of most of the magic methods.".
使用 Mock,您可以模拟魔术方法,但您必须定义它们。MagicMock 具有“大多数魔术方法的默认实现”。.
If you don't need to test any magic methods, Mock is adequate and doesn't bring a lot of extraneous things into your tests. If you need to test a lot of magic methods MagicMock will save you some time.
如果你不需要测试任何魔法方法,Mock 就足够了,不会给你的测试带来很多无关紧要的东西。如果你需要测试很多魔法方法,MagicMock 会为你节省一些时间。
回答by user2916464
This is what python's official documentationsays:
这是python的官方文档所说的:
In most of these examples the Mock and MagicMock classes are interchangeable. As the MagicMock is the more capable class it makes a sensible one to use by default.
在大多数这些示例中,Mock 和 MagicMock 类是可以互换的。由于 MagicMock 是功能更强大的类,因此默认情况下使用它是一个明智的选择。
回答by Ryne Everett
What is the reason for plain Mockexisting?
普通Mock存在的原因是什么?
Mock's author, Michael Foord, addressed a very similar question at Pycon 2011 (31:00):
Mock 的作者 Michael Foord在 Pycon 2011 (31:00) 上提出了一个非常相似的问题:
Q:Why was MagicMock made a separate thing rather than just folding the ability into the default mock object?
A:One reasonable answer is that the way MagicMock works is that it preconfigures all these protocol methods by creating new Mocks and setting them, so if every new mock created a bunch of new mocks and set those as protocol methods and then all of those protocol methods created a bunch more mocks and set them on their protocol methods, you've got infinite recursion...
What if you want accessing your mock as a container object to be an error -- you don't want that to work? If every mock has automatically got every protocol method, then it becomes much more difficult to do that. And also, MagicMock does some of this preconfiguring for you, setting return values that might not be appropriate, so I thought it would be better to have this convenience one that has everything preconfigured and available for you, but you can also take a ordinary mock object and just configure the magic methods you want to exist...
The simple answer is: just use MagicMock everywhere if that's the behavior you want.
问:为什么 MagicMock 制作了一个单独的东西,而不是将能力折叠到默认的模拟对象中?
A:一个合理的答案是,MagicMock 的工作方式是它通过创建新的 Mock 并设置它们来预先配置所有这些协议方法,所以如果每个新的 Mock 创建一堆新的 Mock 并将它们设置为协议方法,然后所有这些协议方法创建了更多的模拟并将它们设置在他们的协议方法上,你有无限递归......
如果您希望将您的模拟作为容器对象访问是一个错误 - 您不希望它起作用怎么办?如果每个模拟都自动获得了每个协议方法,那么这样做会变得更加困难。而且,MagicMock 为你做了一些这样的预配置,设置了可能不合适的返回值,所以我认为最好有这个方便的,它预先配置了所有的东西并可供你使用,但你也可以使用一个普通的模拟对象,只需配置你想要存在的魔法方法......
简单的答案是:如果这是您想要的行为,只需在任何地方使用 MagicMock。
回答by user650654
To begin with, MagicMockis a subclass of Mock.
首先,MagicMock是 的子类Mock。
class MagicMock(MagicMixin, Mock)
As a result, MagicMock provides everything that Mock provides and more. Rather than thinking of Mock as being a stripped down version of MagicMock, think of MagicMock as an extended version of Mock. This should address your questions about why Mock exists and what does Mock provide on top of MagicMock.
因此,MagicMock 提供了 Mock 提供的一切以及更多。与其将 Mock 视为 MagicMock 的精简版,不如将 MagicMock 视为 Mock 的扩展版本。这应该可以解决您关于 Mock 为什么存在以及 Mock 在 MagicMock 之上提供什么的问题。
Secondly, MagicMock provides default implementations of many/most magic methods, whereas Mock doesn't. See herefor more information on the magic methods provided.
其次,MagicMock 提供了许多/大多数魔术方法的默认实现,而 Mock 则没有。有关提供的魔术方法的更多信息,请参见此处。
Some examples of provided magic methods:
提供的魔术方法的一些示例:
>>> int(Mock())
TypeError: int() argument must be a string or a number, not 'Mock'
>>> int(MagicMock())
1
>>> len(Mock())
TypeError: object of type 'Mock' has no len()
>>> len(MagicMock())
0
And these which may not be as intuitive (at least not intuitive to me):
而这些可能不那么直观(至少对我来说不直观):
>>> with MagicMock():
... print 'hello world'
...
hello world
>>> MagicMock()[1]
<MagicMock name='mock.__getitem__()' id='4385349968'>
You can "see" the methods added to MagicMock as those methods are invoked for the first time:
当这些方法第一次被调用时,您可以“看到”添加到 MagicMock 的方法:
>>> magic1 = MagicMock()
>>> dir(magic1)
['assert_any_call', 'assert_called_once_with', ...]
>>> int(magic1)
1
>>> dir(magic1)
['__int__', 'assert_any_call', 'assert_called_once_with', ...]
>>> len(magic1)
0
>>> dir(magic1)
['__int__', '__len__', 'assert_any_call', 'assert_called_once_with', ...]
So, why not use MagicMock all the time?
那么,为什么不一直使用 MagicMock 呢?
The question back to you is: Are you okay with the default magic method implementations? For example, is it okay for mocked_object[1]to not error? Are you okay with any unintended consequences due to the magic method implementations being already there?
回到您的问题是:您是否同意默认的魔术方法实现?例如,mocked_object[1]不出错可以吗?由于魔术方法实现已经存在,您是否可以接受任何意外后果?
If the answer to these questions is a yes, then go ahead and use MagicMock. Otherwise, stick to Mock.
如果这些问题的答案是肯定的,那么继续使用 MagicMock。否则,坚持模拟。
回答by Manu
I've found another particular case where simpleMockmay turn more useful than MagicMock:
我发现了另一种特殊情况,其中simpleMock可能比MagicMock以下更有用:
In [1]: from unittest.mock import Mock, MagicMock, ANY
In [2]: mock = Mock()
In [3]: magic = MagicMock()
In [4]: mock.foo == ANY
Out[4]: True
In [5]: magic.foo == ANY
Out[5]: False
Comparing against ANYcan be useful, for example, comparing almost every key between two dictionaries where some value is calculated using a mock.
比较ANY可能很有用,例如,比较两个字典之间的几乎每个键,其中一些值是使用模拟计算的。
This will be valid if you're using Mock:
如果您正在使用,这将是有效的Mock:
self.assertDictEqual(my_dict, {
'hello': 'world',
'another': ANY
})
while it will raise an AssertionErrorif you've used MagicMock
AssertionError如果你使用过它,它会提高一个MagicMock

![Python socket.error: [Errno 111] 尝试连接到套接字时](/res/img/loading.gif)