Para começar, MagicMock
é uma subclasse de Mock
.
class MagicMock(MagicMixin, Mock)
Como resultado, o MagicMock fornece tudo o que o Mock fornece e muito mais. Em vez de pensar no Mock como uma versão simplificada do MagicMock, pense no MagicMock como uma versão estendida do Mock. Isso deve responder às suas perguntas sobre por que o Mock existe e o que o Mock fornece sobre o MagicMock.
Em segundo lugar, o MagicMock fornece implementações padrão de muitos / a maioria dos métodos mágicos, enquanto o Mock não. Veja aqui para mais informações sobre os métodos mágicos fornecidos.
Alguns exemplos de métodos mágicos fornecidos:
>>> 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
E estes que podem não ser tão intuitivos (pelo menos não intuitivos para mim):
>>> with MagicMock():
... print 'hello world'
...
hello world
>>> MagicMock()[1]
<MagicMock name='mock.__getitem__()' id='4385349968'>
Você pode "ver" os métodos adicionados ao MagicMock quando esses métodos são chamados pela primeira vez:
>>> 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', ...]
Então, por que não usar o MagicMock o tempo todo?
A pergunta de volta para você é: Você concorda com as implementações padrão do método mágico? Por exemplo, não há problema em mocked_object[1]
não errar? Você concorda com quaisquer conseqüências não intencionais devido às implementações do método mágico já estarem lá?
Se a resposta a essas perguntas for afirmativa, vá em frente e use o MagicMock. Caso contrário, atenha-se ao mock.