Комментарии 10
В дополнение к VCR посоветую еще пару джемов, которые мы используем вместе с VCR:
Whisperer — github.com/dnesteryuk/whisperer — этот джем позволяет описать на руби ответ сервера и сгенерировать фикстуру, так что не нужно записывать их вручную. Этим мы упрощает редактирование кассет в будущем, когда меняется структура ответа от сервера так что нам достаточно будет обновить объект и перегенерировать фикстуры. Ну и доступны плюшки в виде наследования и прочее — мануал достаточно хорошо =)
и второй — SitePrism.Vcr github.com/dnesteryuk/site_prism.vcr — позволяет использовать VCR вместе с SitePrism
Whisperer — github.com/dnesteryuk/whisperer — этот джем позволяет описать на руби ответ сервера и сгенерировать фикстуру, так что не нужно записывать их вручную. Этим мы упрощает редактирование кассет в будущем, когда меняется структура ответа от сервера так что нам достаточно будет обновить объект и перегенерировать фикстуры. Ну и доступны плюшки в виде наследования и прочее — мануал достаточно хорошо =)
и второй — SitePrism.Vcr github.com/dnesteryuk/site_prism.vcr — позволяет использовать VCR вместе с SitePrism
Скажите, а почему не используется подход «делаем тонкий адаптер стороннего сервиса, затем подменяем адаптер»?
Я не совсем понял предлагаемый принцип, если можно приведите пример. Если я правильно понял, имеется в виду написать тонкий адаптер, например для общения с фейсбуком, и потом подменять адаптер mock объектами?
Да, именно это я и имею в виду.
Данный принцип не использовался так как с внешним сервисом общался gem Koala, то есть адаптер был сторонним. Создать mock объект было бы слишком накладно. Стоит так же отметить, что если мы говорим непосредственно об объекте — не всегда была бы возможность его вызвать, например в функциональных тестах моего API, потому что запросы идут через него, а только потом попадают в нужный объект.
Можно использовать ServiceLocator:
А если в каких то тестах нужен оригинальный Koala, то
Соответственно везде используем ServiceLocator.facebook_client
#lib/service_locator.rb
module ServiceLocator
mattr_accessor(:facebook_client) { Koala }
end
#test/support/fake_koala.rb
class FakeKoala
#some methods
end
#test/test_helper.rb
#...
ServiceLocator.facebook_client = FakeKoala
#...
А если в каких то тестах нужен оригинальный Koala, то
def with_real_koala
previous = ServiceLocator.facebook_client
ServiceLocator.facebook_client = Koala
yield
ServiceLocator.facebook_client = previous
end
with_real_koala do
#some code
end
Соответственно везде используем ServiceLocator.facebook_client
#lib/some_file.rb
class SomeFile
include ServiceLocator
def some_method
facebook_client.some_facebook_api_method
end
end
Мы через это прошли, идея оказалась не удачной. VCR cassettes содержат запросы к API и ответы к ним. Таким образом, если после upgrade какой-то библиотеки для работы с API меняеться запрос (а значит есть шанс что запрос уже не правильный), вы сразу узнаете где ваш функционал возможно перестанет работать.
С подменой адаптера вы не узнаете когда ваше приложение перестанет правильно работать с API, поддержка такого адаптера это головная боль.
С подменой адаптера вы не узнаете когда ваше приложение перестанет правильно работать с API, поддержка такого адаптера это головная боль.
С другой стороны, если вы фиксируете запросы и ответы, то вы не узнаете, что изменилось API — так что вам все равно нужны интеграционные тесты. Соответственно, если вы используете неконтролируемую вами библиотеку для работы с API, то она просто находится с другой стороны от интеграционных тестов, и тестировать ее взаимодействие с API не надо.
У подхода «мокаем внешние сервисы» есть существенный недостаток: в итоге тестируются моки, а не сами интеграции со внешними сервисами. Например, если API внешнего сервиса изменится, то тесты вам этого не покажут.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Убиваем внешние запросы во время тестирования rails приложений с помощью VCR