В Python's unittest.mock, и Mock, и MagicMock используются для создания объектов-заглушек, которые можно использовать для замены зависимостей в ваших тестах.  Основное различие между ними заключается в том, как они обрабатывают "магические" методы (также известные как dunder methods) Python, такие как __str__, __len__, __add__ и т.д.
Mock:
Mock является более базовым классом.  Он ведет себя как обычный объект Python.Mock, то получите исключение AttributeError, если этот метод не был специально настроен для возврата чего-либо.Mock корректно имитировал объект, поддерживающий магические методы, вам нужно явно настроить эти методы, указав для них возвращаемые значения или побочные эффекты.MagicMock:
MagicMock наследуется от Mock, но автоматически предоставляет реализации для большинства магических методов.MagicMock объекте, он возвращает другой MagicMock объект по умолчанию. Это означает, что вызовы магических методов "просто работают" без необходимости явной настройки.MagicMock более удобным и менее подверженным ошибкам в сценариях, где вам нужно имитировать объекты, которые интенсивно используют магические методы.  Например, имитация контейнера, который поддерживает операции сравнения, сложения или определения длины.Пример:
Допустим, вы хотите имитировать объект, который поддерживает операцию сложения (__add__). С Mock вам нужно будет:
   my_mock = Mock(); my_mock.__add__ = Mock(return_value=5).
   С MagicMock это уже настроено по умолчанию.
  
Когда использовать что?
Mock, когда вам нужен простой объект-заглушка и вы контролируете все аспекты его поведения, особенно если он не использует магические методы.MagicMock, когда вам нужно имитировать объекты, которые интенсивно используют магические методы, чтобы избежать явной настройки каждого метода. Это упрощает и ускоряет написание тестов.В целом, MagicMock - это более мощный и удобный инструмент, который часто является лучшим выбором по умолчанию, если вы не уверены, какой класс использовать.