Я в некотором затруднении в отношении того, как написать полноценный приемочный тест, который включает в себя на нижних уровнях взаимодействие с дорогим сетевым вызовом, которого я стараюсь избегать.
Я использую 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, скажите мне, каков обычный метод проведения такого типа тестирования?