Как игнорировать совпадение тела запроса для определенного хоста в rspec VCR?

У меня есть интеграция ElasticSearch и Kibana с моим приложением rails, и я использую их для регистрации и измерения запросов к внешним API. Я не хочу, чтобы VCR соответствовал телу для записей запросов ElasticSearch, потому что в каждом журнале есть поле «текущее время» (created_at), которое ломает старые записи VCR.

Это моя текущая конфигурация

VCR.configure do |c|
  c.ignore_localhost = true
  c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'

  vcr_mode = ENV['VCR_MODE'] =~ /rec/i ? :all : :once

  c.hook_into :webmock
  c.default_cassette_options[:record] = vcr_mode
  c.configure_rspec_metadata!
end

Это метод журнала в моем пользовательском клиенте REST.

  def log(method, params, response, comments:)
    Rails.logger.info(response.inspect)

    Elastic::LogServices
      .log_request(comments,
                   method: method,
                   source: ENV['HOSTNAME'],
                   url: response.env.url.to_s,
                   header: response.env.request_headers,
                   body: params,
                   type: :out,
                   response_header: response.headers,
                   response_body: response.body,
                   response_status: response.status)
  end

В журнале сервисов...

    def self.log_request(comments = '',
                         created_at: nil,
                         method:,
                         source:,
                         url:,
                         header:,
                         body:,
                         type:,
                         response_header:,
                         response_body: '?',
                         response_status:,
                         format: 'REST')
      log =
        Elastic::Request::Log
        .new(created_at: created_at,
             method: method,
             source: source,
             url: url,
             header: header,
             body: JSON.pretty_generate(body),
             type: type,
             response:
              {
                header: response_header,
                body: JSON.pretty_generate(response_body),
                status: response_status
              },
             format: format,
             comments: comments)

      Elastic::Request::LogJob.perform_async(log)
    end

Это поле находится в классе объектов журнала.

        @created_at = created_at || Time.now.utc.iso8601

Кроме того, я не хочу имитировать метод «Time.now.utc.iso8601», потому что мне нужно изменить множество тестов. Приложение делает много запросов к другим API.

В любом случае, настроить VCR так, чтобы он игнорировал совпадение тела для всех запросов «elasticsearch: 9200»?


person Henrique Fernandez Teixeira    schedule 25.03.2019    source источник
comment
Вы можете использовать timecop gem, чтобы остановить время в определенный момент   -  person Martin Zinovsky    schedule 26.03.2019
comment
Или вы можете написать собственный сопоставитель, чтобы игнорировать поле created_at в теле ответа. Ознакомьтесь с this article   -  person Martin Zinovsky    schedule 26.03.2019
comment
Или вы можете сопоставить другие атрибуты, чтобы игнорировать сопоставление тела, поскольку оно меняется каждый раз. Ознакомьтесь с request-matching docs. Как видите, у вас есть много вариантов на выбор   -  person Martin Zinovsky    schedule 26.03.2019
comment
Я решил проблему, имитируя метод сохранения всех моих экземпляров ElasticRepository в тестовой среде с помощью before(:all). Спасибо за ответ.   -  person Henrique Fernandez Teixeira    schedule 27.03.2019


Ответы (1)


Можешь попробовать:

VCR.configure do |c|
  c.ignore_localhost = true
  c.cassette_library_dir = 'spec/fixtures/vcr_cassettes'
  c.register_request_matcher :body do |request1, request2|
    if request1.uri.include?('<your_host>')
      true
    else
      CGI.escape(request1.body) == CGI.escape(request2.body)
    end
  end

  c.hook_into :webmock
  c.configure_rspec_metadata!
end
person Saurabh Jain    schedule 17.06.2020