Pull to refresh

Comments 10

В дополнение к VCR посоветую еще пару джемов, которые мы используем вместе с VCR:
Whisperer — github.com/dnesteryuk/whisperer — этот джем позволяет описать на руби ответ сервера и сгенерировать фикстуру, так что не нужно записывать их вручную. Этим мы упрощает редактирование кассет в будущем, когда меняется структура ответа от сервера так что нам достаточно будет обновить объект и перегенерировать фикстуры. Ну и доступны плюшки в виде наследования и прочее — мануал достаточно хорошо =)

и второй — SitePrism.Vcr github.com/dnesteryuk/site_prism.vcr — позволяет использовать VCR вместе с SitePrism
Скажите, а почему не используется подход «делаем тонкий адаптер стороннего сервиса, затем подменяем адаптер»?
Я не совсем понял предлагаемый принцип, если можно приведите пример. Если я правильно понял, имеется в виду написать тонкий адаптер, например для общения с фейсбуком, и потом подменять адаптер mock объектами?
Да, именно это я и имею в виду.
Данный принцип не использовался так как с внешним сервисом общался gem Koala, то есть адаптер был сторонним. Создать mock объект было бы слишком накладно. Стоит так же отметить, что если мы говорим непосредственно об объекте — не всегда была бы возможность его вызвать, например в функциональных тестах моего API, потому что запросы идут через него, а только потом попадают в нужный объект.
Можно использовать ServiceLocator:

#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 внешнего сервиса изменится, то тесты вам этого не покажут.
Поэтому и существуют отдельно функциональные тесты и интеграционные тесты. в статье речь о первых.
Sign up to leave a comment.

Articles