Подтвердить что ты не робот

В чем разница между mocks, stubs и поддельными объектами

Хотя ресурсов много, даже здесь, на SO, только два из этих терминов сравниваются друг с другом в этих Q/A.

Итак, словом, какой из них? И как все они связаны друг с другом? Или они не совсем?

4b9b3361

Ответ 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 (имя старое, но никакого видимого различия не делается, будь то заглушка или макет)

Ссылки, дальнейшее чтение

Ответ 2

Mock и Stub называются Fake Object. По-моему:

  • Штук используется для замены внешней зависимости, поэтому наши тесты выполняются без исключений. Мы должны использовать Assert для определения отказа теста или нет. Stub подходит только для проверки результата, некоторые из которых являются правильными или нет.

  • Макет более сложный, часто используемый для тестирования поведения, например. проверка - это функция, называемая или не

Ответ 3

Они, как правило, взаимозаменяемы, но есть небольшие различия по моему мнению.

  • Макет/поддельный объект вернет реалистичные результаты.
  • Штук вернет значение отказа/пропуска по умолчанию.