Как я могу структурировать этот класс, чтобы я мог проводить как можно больше юнит-тестирования? - PullRequest
1 голос
/ 25 марта 2011

Добрый вечер,

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

Пример из проекта, над которым я сейчас работаю: у него есть класс, который выполняет поиск LDAP в Active Directory с использованием DirectorySearcher и возвращает результаты в виде объектов Person. Моим первым желанием было получить интерфейс для DirectorySearcher, а затем создать довольно сложную заглушку, которую я могу использовать для тестирования. Однако это оказалось проблематичным, поскольку DirectorySearcher, похоже, не использует интерфейс, и для его успешного завершения потребовалось бы много кода.

Моей следующей мыслью было создание класса Searcher, который внутренне использует DirectorySearcher, который позволил бы мне проверить соответствие между результатами LDAP и отображением объекта Person, но это не сильно меня поразило, и это еще один уровень абстракции. .

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

Спасибо!

Ответы [ 3 ]

5 голосов
/ 25 марта 2011

Если у вас есть класс, который вы не можете внедрить в зависимости, то лучшим вариантом будет создание объекта-обертки и обтекание этого объекта. Затем вы можете добавить свою оболочку (или макет этой оболочки), чтобы получить эту функциональность.

Так что в вашем случае вы были правы, создав класс оболочки "Searcher", который внутренне вызывает DirectorySearcher. Какие бы методы вы ни вызывали в DirectorySearcher, вы предоставляете их в своем классе Searcher как виртуальные методы. Затем вы можете создать класс фиктивного поисковика с переопределенными методами и внедрить его при модульном тестировании (или же Moq создаст его для вас!)

1 голос
/ 25 марта 2011

Из того, что я могу понять, ваш класс (давайте назовем его "PeoplePerson" для обсуждения) должен захватывать / охватывать людей на основе определенных критериев. Так что можно с уверенностью сказать, что вашему классу нужен PeopleRepository. Мы будем беспокоиться о том, как PeopleRepository сможет обслуживать вызовы, такие как «GetPeople (критерии)» позже. Теперь, если вы протестируете разработку PeoplePerson, вы скоро найдете подходящих членов интерфейса (и они обычно склонны к технологическому / импл. Агностику). Используйте фальшивый фреймворк (я предполагаю, что LDAP сделает ваши юнит-тесты медленнее), чтобы ввести макет в PeoplePerson

public PeoplePerson (IPeopleRepository хранилище) {... // кэшировать его}

Теперь выясните, как можно реализовать каждый метод в IPeopleRepository. Напишите тесты для PeopleRepository, которые работают против реального поставщика ActiveServer / LDAP, оборачивающего известный набор данных. Эти тесты будут медленными (интеграционные тесты, которые тестируют интеграцию с ActiveServer), но они освобождают всех от беспокойства о LDAP / ActiveServer.

Я считаю создание этой абстракции хорошей инвестицией.

0 голосов
/ 25 марта 2011

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

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