Ошибка необработанного HTTP-запроса видеомагнитофона

Мои спецификации перейдут в основную ветку. Если я создам новую ветку и изменю какой-то код, совершенно не связанный с подписками, они потерпят неудачу с этим. Единственный способ, которым я могу заставить их пройти, - это изменить мой файл vcr.rb на :record => :new_episodes.

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

Любые предложения о том, как справиться с этим? Многие спецификации, которые ломаются, основаны на этом сопоставителе:

  describe "#change_plan_to", vcr: {match_requests_on: [:method, :uri, :body]} do

Этот сопоставитель слишком открыт для изменений? Я не смог передать спецификации каким-либо другим способом с помощью вызовов Stripe API.

Failure/Error: @subscription.create_stripe_customer
     VCR::Errors::UnhandledHTTPRequestError:


       ================================================================================
       An HTTP request has been made that VCR does not know how to handle:
         POST https://api.stripe.com/v1/customers

       VCR is currently using the following cassette:
         - /Users/app/spec/data/Subscription/_change_plan_to/stripe_customer_subscription_plan_/name/.json
         - :record => :once
         - :match_requests_on => [:method, :uri, :body]

       Under the current configuration VCR can not find a suitable HTTP interaction
       to replay and is prevented from recording new requests. There are a few ways
       you can deal with this:

         * If you're surprised VCR is raising this error
           and want insight about how VCR attempted to handle the request,
           you can use the debug_logger configuration option to log more details [1].
         * You can use the :new_episodes record mode to allow VCR to
           record this new request to the existing cassette [2].
         * If you want VCR to ignore this request (and others like it), you can
           set an `ignore_request` callback [3].
         * The current record mode (:once) does not allow new requests to be recorded
           to a previously recorded cassette. You can delete the cassette file and re-run
           your tests to allow the cassette to be recorded with this request [4].
         * The cassette contains 109 HTTP interactions that have not been
           played back. If your request is non-deterministic, you may need to
           change your :match_requests_on cassette option to be more lenient
           or use a custom request matcher to allow it to match [5].

       [1] https://www.relishapp.com/vcr/vcr/v/2-5-0/docs/configuration/debug-logging
       [2] https://www.relishapp.com/vcr/vcr/v/2-5-0/docs/record-modes/new-episodes
       [3] https://www.relishapp.com/vcr/vcr/v/2-5-0/docs/configuration/ignore-request
       [4] https://www.relishapp.com/vcr/vcr/v/2-5-0/docs/record-modes/once
       [5] https://www.relishapp.com/vcr/vcr/v/2-5-0/docs/request-matching
       ================================================================================
     # ./app/models/subscription.rb:83:in `create_stripe_customer'
     # ./spec/models/subscription_spec.rb:68:in `block (3 levels) in <top (required)>'
     # -e:1:in `<main>'

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


person Ecl1pse Armageddon    schedule 23.07.2013    source источник


Ответы (1)


Поведение, которое вы видите, предполагает, что один из атрибутов, используемых для сопоставления запросов, не является детерминированным и изменяется каждый раз, когда вы запускаете тесты. Вы упомянули об использовании опции match_requests_on: [:method, :uri, :body] -- я предполагаю, что это body. Имейте в виду, что встроенный в VCR механизм сопоставления тел выполняет прямое body_string == body_string сравнение, и легко могут возникнуть ситуации, когда тела семантически эквивалентны, но не являются одной и той же строкой. Например, строка JSON типа {"a": 1", "b": 2} vs {"b": 2, "a": 1}.

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

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

person Myron Marston    schedule 24.07.2013
comment
Большое спасибо за ваш проницательный ответ. Если я удалю тело, то спецификации не пройдут... есть предложения, как с этим справиться? Я включу отладчик и вставлю то, что вижу. - person Ecl1pse Armageddon; 25.07.2013
comment
Вот ошибка, которую я получаю: gist.github.com/anonymous/0661a0e821ae907de0e3 и спецификация: gist.github.com/anonymous/588697967840ee97317f - person Ecl1pse Armageddon; 25.07.2013
comment
также я читал о том, что было раньше, поэтому я попробовал это, и это все равно не работает: 672bf704fd7ae3aec989 - person Ecl1pse Armageddon; 25.07.2013
comment
Я еще поиграл с этим, и все еще получаю ошибки... пользователь не обновляет по электронной почте? gist.github.com/anonymous/adc73d906da075389f40 - person Ecl1pse Armageddon; 25.07.2013
comment
Я не могу решить вашу проблему удаленно, извините. Тем не менее, одна из возможностей заключается в том, что некоторые из вещей, о которых вы утверждаете, недетерминированы. Например, если идентификатор пользователя отличается при каждом запуске теста, но записывается на кассету как определенное значение, то в следующий раз при воспроизведении ожидаемое значение может быть другим (из-за недетерминизма), но кассета будет воспроизводить записанное значение, и это может привести к сбою. - person Myron Marston; 25.07.2013
comment
Что делает тест, так это то, что он создает пользователя. Затем клиент с чередованием, у которого есть токен клиента, этот токен клиента сохраняется в этой модели подписки. Когда я беру модель подписки, она говорит, что у нее другой клиент. Это тянет старый против правильного - если есть новые эпизоды, этого не происходит. В данном случае это извлечение данных API из полосы и определение электронной почты. Ответ от vcr/stripe — это старое электронное письмо, а не электронное письмо фактического объекта в тесте. - person Ecl1pse Armageddon; 26.07.2013
comment
Извините, я просто хочу разобраться... заводской пользователь: [email protected]. заводская подписка [email protected] заводская подписка токен клиента после вызова API: cus_2GTDs43sbCtUN9 чередовать клиента по электронной почте токена: [email protected] — в тестовых данных чередования этот токен клиента отправляется на bob2example.com, но на этапе фабрики мы ссылаемся на bob1 @example.com. Видеомагнитофон возвращает другой/старый ответ. Как это исправить? - person Ecl1pse Armageddon; 26.07.2013
comment
В общем, есть 3 стратегии, которые, как правило, работают для этих проблем: (1) найти способ устранить недетерминизм. (2) Вставьте заполнители в кассету для недетерминированных значений. Вот для чего эта опция: .com/vcr/vcr/v/2-5-0/docs/configuration/ (3) Напишите собственный сопоставитель запросов VCR, который игнорирует недетерминированные части, не идентифицирующие запрос. Вы также можете изучить использование хуков видеомагнитофона — relishapp.com/ vcr/vcr/v/2-5-0/docs/hooks -- чтобы делать еще более сложные вещи. - person Myron Marston; 26.07.2013