Жестко запрограммированные объекты Mock против Mocking Framework - PullRequest
10 голосов
/ 06 декабря 2010

Мне интересно, какой метод люди любят использовать для насмешек, и , почему .Мне известны два метода: использование жестко закодированных фиктивных объектов и фреймворка.Для демонстрации я приведу пример с использованием C #.

Предположим, у нас есть интерфейс IEmployeeRepository с методом GetEmployeeById.

public interface IEmployeeRepository
{
    Employee GetEmployeeById(long id);
}

Мы можем легко создать макет этого:

public class MockEmployeeRepository : IEmployeeRepository
{
    public Employee GetEmployeeById(long id)
    {
        Employee employee = new Employee();
        employee.FirstName = "First";
        employee.LastName = "Last";
        ...
        return employee;
    }
}

Затем в наших тестах мы можем явно указать нашим службам использовать MockEmployeeRepository, используя либо метод установки, либо внедрение зависимостей.Я новичок в фальсификации фреймворков, поэтому мне любопытно, почему мы их используем, если мы можем просто сделать выше?

Ответы [ 6 ]

11 голосов
/ 06 декабря 2010

Это не издевательство, это заглушка. Для заглушки ваш пример вполне приемлем.

От Мартина Фаулера:

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

Когда вы что-то издеваетесь, вы обычно вызываете метод «Проверка».

Посмотрите на это для различия между Моксом и Окурками http://martinfowler.com/articles/mocksArentStubs.html

4 голосов
/ 12 декабря 2010

Я думаю, что выбор между написанием фиктивных объектов вручную или с помощью каркаса во многом зависит от типов компонентов, которые вы тестируете.

Если это является частью контракта для тестируемого компонента наОбщайтесь со своими сотрудниками, следуя точному протоколу, и тогда вам нужно использовать инструментальные фиктивные объекты («Mocks»).Зачастую такие протоколы намного проще тестировать с использованием фальшивой инфраструктуры, чем путем ручного кодирования.Рассмотрим компонент, который необходим для открытия репозитория, выполнения некоторых операций чтения и записи в установленном порядке, а затем закрытия репозитория - даже перед лицом исключения.Фальсифицирующая структура облегчит настройку всех необходимых тестов.Приложения, относящиеся к телекоммуникациям и управлению процессами (чтобы выбрать пару случайных примеров), полны компонентов, которые необходимо протестировать таким образом.

С другой стороны, многие компоненты в общих бизнес-приложениях не имеют особых ограничений.о том, как они общаются со своими сотрудниками.Рассмотрим компонент, который выполняет некоторый анализ, скажем, нагрузки университетского курса.Компонент должен получить информацию о преподавателе, студенте и курсе из хранилища.Но не имеет значения, в каком порядке он извлекает данные: инструктор-студент-курс, студент-курс-инструктор, все сразу или что угодно.Нет необходимости проверять и применять шаблон доступа к данным.Действительно, было бы вредно тестировать этот шаблон, так как это потребовало бы конкретной реализации без необходимости.В этом контексте простые неструктурированные фиктивные объекты («Заглушки») являются адекватными, а фальшивый фреймворк, вероятно, излишним.

Я должен отметить, что даже при работе с фреймворком фреймворк может значительно облегчить вашу жизнь.Не всегда можно себе позволить диктовать подписи своих сотрудников.Представьте себе модульное тестирование компонента, который необходим для обработки данных, полученных из толстого интерфейса, например IDataReader или ResultSet .Ручная обработка таких интерфейсов в лучшем случае неприятна - особенно если тестируемый компонент фактически использует только три из множества методов в интерфейсе.

Для меня проекты, для которых требовались фреймворки, почти всегда былихарактер системного программирования (например, проекты базы данных или веб-инфраструктуры, или низкоуровневая сантехника в бизнес-приложении).Что касается проектов по разработке приложений, то мой опыт показывает, что в поле зрения было мало насмешек.

Учитывая, что мы всегда стремимся как можно больше скрывать грязные детали инфраструктуры низкого уровня, может показаться, что мы должны стремитьсячтобы простые заглушки намного превосходили количество насмешек.

2 голосов
/ 06 декабря 2010

Некоторые различают издевательства и окурки. Поддельный объект может проверить, что с ним взаимодействовали ожидаемым образом. Фреймворк для насмешек позволяет легко создавать макеты и заглушки.

В вашем примере вы заглушили один метод в интерфейсе. Рассмотрим интерфейс с n методами, где n может меняться со временем. Внедренная вручную реализация может потребовать больше кода и больше обслуживания.

1 голос
/ 08 декабря 2010

Смежный интерфейс может иметь разные выходные данные на тест - в одном тесте у вас может быть метод, возвращающий нуль, в другом тесте метод возвращает объект, в другом тесте метод выдает исключение.Все это настраивается в модульном тесте, в то время как ваша версия потребует нескольких рукописных объектов.

Psuedocode:

//Unit Test One

MockObject.Expect(m => m.GetData()).Return(null);

//Unit Test Two

MockObject.Expect(m => m.GetData()).Return(new MyClass());

//Unit Test Three

MockObject.Expect(m => m.GetData()).ThrowException();
1 голос
/ 07 декабря 2010

Я писал их от руки. У меня были проблемы с использованием Moq, но потом я прочитал TDD: Введение в Moq , и я думаю, что теперь я понимаю, что они говорят о классическом и мокистском подходах. Сегодня вечером я попробую Moq, и я думаю, что понимание подхода «mockist» даст мне то, что мне нужно, чтобы Moq работал лучше для меня.

1 голос
/ 07 декабря 2010

Сначала я пишу заглушки и издевательства вручную. Затем, если это можно легко выразить с помощью фиктивной инфраструктуры объектов, я переписываю ее так, чтобы у меня было меньше кода для обслуживания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...