Методы модульного тестирования, которые вызывают поставщики веб-сервисов

10

У меня есть класс с одним открытым методом Send()и несколькими закрытыми методами. Он вызывает пару веб-сервисов и обрабатывает ответ. Обработка сделана в частных методах.

Я хочу провести модульное тестирование кода. Насколько я понимаю, модульные тесты должны тестировать мой код изолированно (т.е. макетировать ответы поставщиков).

Я также считаю, что частные методы не должны подвергаться модульному тестированию. Но если я просто протестирую метод Send (), мой код не тестируется изолированно и зависит от резонанса поставщика.

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

Извинения, если это основной вопрос, я довольно новичок в модульном тестировании.

Я использую c # и VS2010

Том Сквайрс
источник
Если вы не тестируете приватный метод, как вы узнаете, работает ли он?
Брайан Оукли
1
@BryanOakley вам не нужно знать, что приватный метод работает, он приватный. Вы знаете, что это работает, потому что публичные методы, которые вызывают его, проходят свои тесты.
StuperUser
@ Брайан Оукли взгляните на ссылку
Том Сквайрс
Привет, Том, я обновил ссылку, чтобы сделать ее более заметной и чтобы текст ссылки отражал ее цель. Пожалуйста, не стесняйтесь откат.
StuperUser

Ответы:

18

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

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

Петер Тёрёк
источник
3

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

OC
источник
3

Как уже говорили другие, если ваши модульные тесты имеют внешние зависимости, такие как веб-службы или вызовы базы данных, тогда они НЕ являются модульными тестами вообще, это интеграционные тесты.

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

Мы обходим это с помощью Mocking Framework. Поддельные объекты позволяют нам создавать макет компонента, чтобы компонент в нашем модульном тесте использовал эти фиктивные объекты вместо реальных. Мы можем внедрить фиктивные объекты в тестируемый компонент и указать, какой аргумент (ы) мы ожидаем, что мы хотели бы, чтобы он возвращал при вызове, даже то, какое исключение мы бы хотели выдать. Я настоятельно рекомендую прочитать больше на эту тему, поскольку это улучшит надежность и независимость ваших юнит-тестов.

Хороший пост о различных C # mocking frameworks смотрите в следующей ветке SO:

/programming/37359/what-c-mocking-framework-to-use

РЕДАКТИРОВАТЬ: Для откровенно чувствительных, я буду признавать, что я не упомянул DbUnit или другие инструменты транзакций, которые могут откатить изменения базы данных в конце теста. Они также повторяемы и могут быть независимыми от среды с генерируемыми тестовыми данными, поэтому Mocking Framework в этом случае не требуется.

maple_shaft
источник
Может кто-нибудь объяснить понижение? Я не копировал PHP, ROR, базы данных NoSQL, Javascript на сервере, продукты Apple или любые другие потрясающие тенденции, но я все равно получил пониженное голосование от диска: S
maple_shaft
Я думаю, кому-то не понравилось, когда их юнит-тесты называли «совсем не юнит-тестами» (не я) :)
Даниэль Б.