Ответ 1
Разница между mock и заглушкой очень проста - mock может сделать ваш тест неудачным, а заглушка не может. Это все есть. Кроме того, вы можете думать о заглушке как о чем-то, что обеспечивает ценности. В настоящее время подделка - это всего лишь общий термин для обоих из них (подробнее об этом позже).
Пример
Рассмотрим случай, когда вам нужно создать службу, которая отправляет пакеты по протоколу связи (точные данные неактуальны). Вы просто поставляете сервис с кодом пакета, и все остальное. Учитывая нижеприведенный фрагмент, можете ли вы определить, какая зависимость была бы заглушкой и какие издеваются над потенциальным unit test?
public class DistributionService
{
public double SendPackage(string packageCode)
{
var contents = this.packageService.GetPackageContents(packageCode);
if (contents == null)
{
throw new InvalidOperationException(
"Attempt to send non-exisiting package");
}
var package = this.packageBuilder.Build(contents);
this.packageDistributor.Send(package);
}
}
Довольно легко сказать, что packageBuilder
просто предоставляет значение, и нет никакого возможного способа, чтобы он мог пропустить какой-либо тест. Это заглушка. Даже если это может показаться более расплывчатым, packageService
тоже заглушает. Это дает значение (то, что мы делаем со значением, не имеет значения с точки с заглушкой). Конечно, позже мы будем использовать это значение, чтобы проверить, не выбрасывается ли исключение, но оно все еще находится под нашим контролем (как, в частности, мы говорим, что нужно точно указать, что делать и забывать об этом - это не должно оказывать никакого влияния на тест).
Это отличается от packageDistributor
. Даже если он обеспечивает какую-либо ценность, он не потребляется. Однако вызов Send
представляется довольно важной частью нашей реализации, и мы, скорее всего, хотим, чтобы подтвердил его имя.
В этот момент мы должны прийти к выводу, что packageDistributor
является mock. У нас будет выделенный unit test, утверждающий, что был вызван метод Send
, и если по каким-то причинам его не было - мы хотим знать, что это важная часть всего процесса. Другие зависимости - это заглушки, поскольку все, что они делают, - это предоставление значений другим, возможно, более значимым фрагментам кода.
Быстрый взгляд на TDD
Штук, являющийся заглушкой, может быть просто заменен постоянным значением в наивной реализации:
var contents = "Important package";
var package = "<package>Important package</package>";
this.packageDistributor.Send(package);
Это, по сути, то, что насмешливые фреймворки делают с заглушками - инструктируйте их вернуть настраиваемое/явное значение. Старые школы, ручные свертки часто делают именно это - возвращают постоянную ценность.
Очевидно, что такой код не имеет большого смысла, но любой, кто когда-либо делал TDD, наверняка видел кучу таких наивных реализаций на ранней стадии развития класса. Итеративная разработка, которая возникает из TDD, часто помогает идентифицировать роли зависимостей вашего класса.
В настоящее время скрыты, издевательства и подделки
В начале этого сообщения я упомянул, что подделка - это всего лишь общий термин. Учитывая, что макет может также служить в качестве заглушки (особенно в современных смехотворных рамках), во избежание путаницы хорошая идея назвать такой объект подделкой. В настоящее время вы можете видеть, что эта тенденция возрастает - оригинальное макетное различие постепенно уходит в прошлое и используются более универсальные имена. Например:
- FakeItEasy использует подделку
- NSubstitute использует замену
- Moq использует mock (имя старое, но никакого видимого различия не делается, будь то заглушка или макет)
Ссылки, дальнейшее чтение
- Mocks не являются заглушками Мартином Фаулером - вы можете видеть, что эта статья связана практически с любым вопросом заглушки/макета, и это по какой-либо причине
- Изучение континуума двойных тестов Марк Сееманн - обзор для всей запутанной терминологии единицы тестирования (если вы считали, что макет, подделка и заглушки достаточно, вы, вероятно, должны знать там также манекен *, шпион, двойной, а что нет)
- xunitpatterns.com - резервный веб-сайт для огромной книги с модульными тестовыми шаблонами, xUnit Test Patterns: Рефакторинг тестового кода от Gerard Meszaros
- Искусство модульного тестирования Рой Ошерове - отличная модульная тестовая вводная книга ( "макет может сделать тест неудачным, заглушка" Рой слова, а не мои)