Издевательство над дорогим ресурсом в приемочных тестах (rspec, cucumber) - PullRequest
2 голосов
/ 13 декабря 2011

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

Я использую rspec и огурец, и большую часть моего насмешки я использую с помощью rspeck.

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

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

Я написал класс WebServiceInterface, который отвечает за получение имени продукта питания, выполнение соответствующего запроса через веб-сервис и возврат ответа xml. Затем другой вспомогательный класс анализирует ответ xml и возвращает коллекцию информации о питании, которая затем используется в экземпляре ингредиента.

Теперь я уже написал набор модульных тестов, в которых используется WebServiceInterface. Это выглядит примерно так


fake-webservice = double('WebserviceInterface')
fake-webservice.should_receive(:get_response_xml).with(ingredient).and_return(fake_xml_response)

result = ResponseParser.new(fake-webservice).get_ingredient_nutritional_info
result.calories.should eql(123)
result.saturated_fat.should eql(10)

Обратите внимание, что get_response_xml вызывается внутренне анализатором ответа. В этом случае ResponseParser вызывает get_response_xml для введенного fake-webservice.

Для моделей это работает просто отлично, но ситуация сложнее в приемочном тесте. Я хочу написать приемочный тест для страницы, которая проверяет интеграцию между страницей «Создание новых ингредиентов» (new_ingredient_path) и указателем пути к ингредиентам, в котором перечислены все ингредиенты с их пищевой информацией (ingredients_path).

Приемочный тест выглядит примерно так:

visit new_ingredient_path
fill_in 'ingredient_name' :with => 'pickled herring'
click_button 'Create ingredient'
visit ingredients_path
page.should have_content 'Pickled Herring 123 calories 10g saturated fat'

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

Плата за обслуживание по запросу, и я много тестирую, так что «Вы действительно должны тестировать все взаимодействия в интеграционном / приемочном тесте» просто не достаточно для меня в этой ситуации.

Мне нужно найти способ убедиться, что фальшивый веб-сервис или что-то в этом роде используется вместо реального веб-сервиса в тестовой среде (возможно, даже при разработке?). Исходя из .Net фона, типичный ответ, который я привык слышать, это «Используйте Dependency Injection !!? !!». Хотя я думаю, что у DI есть свои достоинства (пожалуйста, не превращайте это в дискуссию о DI), я просто думаю, что здесь есть более простое и легкое решение.

Я, хотя и делаю что-то вроде If ENV["RAILS_ENV"] == 'test', затем использую фальшивку, иначе использую настоящую. Это часто используемая идиома в рельсах или она слишком липкая?

Есть ли способ зарегистрировать это как провайдера определенного типа, который можно настроить, скажем, в блоке spec_helper.rb или в блоке огурца features / support / env.rb?

Мысли, идеи, вклад, советы ???? Может ли опыт работы с Rails dev. и или гуру Cucumber / Rspec, скажите мне, каков обычный метод проведения такого типа тестирования?

1 Ответ

6 голосов
/ 13 декабря 2011

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

В противном случае вы можете использовать webmock, чтобы отключить веб-службу без изменения кода - поскольку вы, похоже, знаете вход и выход веб-службы

http://rubygems.org/gems/webmock

Драгоценный камень VCR, который также использует веб-макок, может использоваться для «записи» и сохранения ответов HTTP, так что вы обращаетесь к веб-сервису только один раз

https://www.relishapp.com/myronmarston/vcr

...