Per cominciare, MagicMockè una sottoclasse di Mock.
class MagicMock(MagicMixin, Mock)
Di conseguenza, MagicMock fornisce tutto ciò che Mock fornisce e altro ancora. Invece di pensare a Mock come una versione ridotta di MagicMock, pensa a MagicMock come una versione estesa di Mock. Questo dovrebbe rispondere alle tue domande sul perché Mock esiste e cosa offre Mock oltre a MagicMock.
In secondo luogo, MagicMock fornisce implementazioni predefinite di molti / molti metodi magici, mentre Mock no. Vedi qui per maggiori informazioni sui metodi magici forniti.
Alcuni esempi di metodi magici forniti:
>>> 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 questi che potrebbero non essere così intuitivi (almeno non intuitivi per me):
>>> with MagicMock():
... print 'hello world'
...
hello world
>>> MagicMock()[1]
<MagicMock name='mock.__getitem__()' id='4385349968'>
Puoi "vedere" i metodi aggiunti a MagicMock poiché questi metodi vengono richiamati per la prima volta:
>>> 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', ...]
Quindi, perché non usare sempre MagicMock?
La domanda che ti viene posta è: stai bene con le implementazioni predefinite del metodo magico? Ad esempio, va bene mocked_object[1]non sbagliare? Stai bene con conseguenze non intenzionali a causa delle implementazioni del metodo magico già presenti?
Se la risposta a queste domande è un sì, allora vai avanti e usa MagicMock. Altrimenti, attenersi a Mock.