В: Почему MagicMock был создан отдельно, а не просто складывал способность в макет объекта по умолчанию?
A: Один разумный ответ заключается в том, что MagicMock работает так, что он предварительно конфигурирует все эти методы протокола, создавая новые Mocks и устанавливая их, поэтому, если каждый новый mock создает кучу новых mock и устанавливает их как методы протокола, а затем все эти протоколы методы создали кучу других макетов и установили их на свои методы протокола, у вас есть бесконечная рекурсия ...
Что если вы хотите, чтобы доступ к макету как к объекту контейнера был ошибкой - вы не хотите, чтобы это работало? Если у каждого макета автоматически есть каждый метод протокола, тогда это становится намного сложнее. Кроме того, MagicMock делает некоторые из этих предварительных настроек для вас, устанавливая возвращаемые значения, которые могут не подходить, поэтому я подумал, что было бы лучше иметь этот удобный, который имеет все предварительно сконфигурированные и доступные для вас, но вы также можете взять обычный макет объект и просто настроить магические методы, которые вы хотите существовать ...
Ответ прост: просто используйте MagicMock везде, если вы хотите именно такого поведения.
С Mock вы можете издеваться над магическими методами, но вы должны определить их. MagicMock имеет «стандартные реализации большинства магических методов». ,
Если вам не нужно тестировать какие-либо магические методы, Mock подходит и не вносит много посторонних вещей в ваши тесты. Если вам нужно протестировать множество магических методов, MagicMock сэкономит вам время.
источник
Начнем с того,
MagicMock
что это подклассMock
.В результате MagicMock предоставляет все, что предлагает Mock, и многое другое. Вместо того, чтобы думать о Mock как об урезанной версии MagicMock, подумайте о MagicMock как о расширенной версии Mock. Это должно ответить на ваши вопросы о том, почему существует Mock и что Mock предлагает поверх MagicMock.
Во-вторых, MagicMock предоставляет реализации многих / большинства магических методов по умолчанию, а Mock - нет. Смотрите здесь для получения дополнительной информации о предоставляемых магических методах.
Некоторые примеры предоставляемых магических методов:
И это может быть не так интуитивно (по крайней мере, не интуитивно для меня):
Вы можете «увидеть» методы, добавленные в MagicMock, когда эти методы вызываются впервые:
Так почему бы не использовать MagicMock все время?
Вопрос, возвращаемый вам: вы согласны с реализациями магического метода по умолчанию? Например, это нормально,
mocked_object[1]
чтобы не ошибка? Вы в порядке с любыми непредвиденными последствиями из-за того, что реализации магических методов уже есть?Если ответ на эти вопросы положительный, тогда используйте MagicMock. В противном случае, придерживайтесь Mock.
источник
Вот что говорится в официальной документации Python :
источник
Я нашел другой конкретный случай, когда простой
Mock
может оказаться более полезным, чемMagicMock
:Сравнение с
ANY
может быть полезным, например, сравнение почти каждого ключа между двумя словарями, где некоторое значение вычисляется с помощью макета.Это будет действительно, если вы используете
Mock
:в то время как это поднимет,
AssertionError
если вы использовалиMagicMock
источник