На днях я немного читал о модульном тестировании и видел несколько примеров, когда люди создают интерфейс репозитория (т.е. IExampleRepository
), а затем создают реальный репозиторий ( public class ExampleRepository : IExampleRepository
) и репозиторий, который будет использоваться для модульного тестирования ( FakeExampleRepository : IExampleRepository
).
В IExampleRepository
них были реализованы те же методы, что и в ExampleRepository
, но с разными запросами Linq.
Какова именно цель здесь? Я думал, что одна часть модульного тестирования вашего кода - убедиться, что метод работает правильно? Но когда я использую два совершенно разных запроса, один для «реального» и один в тесте, какой смысл имеет этот тест?
ExampleRepository
, то лучше использовать издеваться. Оправдание в том, что вы не тестируете хранилище модульно, а что-то еще.ExampleRepository
, используйте настоящее. Если вы проводите модульное тестированиеRepositoryController
, то оно должно использовать только тот,FakeExampleRepository
который возвращает предварительно заданные значения. Таким образом, если ошибка распространяетсяExampleRepository
, только этот модульный тест не пройдёт -RepositoryController
тесты продолжатся успешно, так что вы знаете, что ошибки там нет. Если бы контроллер использовал реальный репозиторий, они оба потерпели бы неудачу, и вы бы не знали, был ли у вас 1 баг или 2Я согласен с двумя ответами от JK. и Ян Худек - они дают действительно хорошую информацию. Но я думал, что добавлю немного.
Ваш первый вопрос («Что именно является целью здесь?») Важен. В случае, если вы описываете, реальная цель состоит в том, чтобы протестировать классы, использующие
IExampleRepository
интерфейс, а не тестировать реализации репозитория. СозданиеFakeExampleRepository
позволяет вам тестировать эти клиентские классы, не беспокоясь о деталях реального класса репозитория.Это особенно верно, если объект, который вы пытаетесь настроить, затрудняет тестирование (например, доступ к файловой системе, вызов веб-службы или связь с базой данных). Используя интерфейсы (и другие подобные методы), вы сохраняете низкий уровень связи. Следовательно, класс
X
должен знать только об интерфейсе и не должен знать о деталях реализации. Цель состоит в том, чтобы убедиться, что классX
делает правильные вещи.Насмешка (или заглушка, подделка ... есть нюансы) - это мощный инструмент для модульного тестирования и TDD. Но может быть боль вручную создавать и поддерживать эти реализации. Таким образом, большинство языков теперь имеют библиотеки-насмешки, чтобы помочь. Поскольку вы используете C #, я бы порекомендовал Moq, потому что он простой и очень мощный. Затем вы можете протестировать интерфейс без накопления лишнего кода для ложных реализаций.
источник
the real objective is to test the classes that are utilizing the IExampleRepository interface
это не совсем верно. Цель состоит в том, чтобы протестировать его независимо от IExampleRepository. +1 за рекомендацию хорошей структуры изоляции, хотя.IExampleRepository
потому что тестируемый класс связан с этим интерфейсом. Но он не зависит от каких-либо реализаций интерфейса. Я признаю, что мое объяснение, возможно, могло бы использовать немного больше изящества все же. :)Изоляция.
Идея модульного тестирования состоит в том, чтобы протестировать наименьшую возможную единицу кода. Вы делаете это, изолируя его от всего другого производственного кода в тесте.
При создании поддельных классов единственным рабочим кодом является тестируемый класс.
Если вы правильно создали поддельное хранилище и тест не прошел, вы знаете, что проблема связана с тестируемым кодом. Это дает вам преимущество диагностики бесплатно.
Взгляните на изолирующие фреймворки (такие как Moq, как предложено @Allan), чтобы иметь возможность быстро сгенерировать эти подделки для настройки условий тестирования и использовать их для подтверждения.
источник
Есть три причины, по которым вы можете захотеть предоставить фиктивный экземпляр для модульного тестирования:
источник