#ruby-on-rails #ruby #rspec #rubygems #vcr
#ruby-on-rails #ruby #rspec #rubygems #Видеомагнитофон
Вопрос:
У меня есть интеграция ElasticSearch и Kibana с моим приложением rails, и я использую их для регистрации и измерения запросов к внешним API. Я не хочу, чтобы видеомагнитофон совпадал с телом для записей запросов ElasticSearch, потому что в каждом журнале есть поле «текущее время» (created_at), которое прерывает старые записи видеомагнитофона.
Это моя текущая конфигурация
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
Это поле находится в классе объектов log
@created_at = created_at || Time.now.utc.iso8601
Кроме того, я не хочу издеваться над методом «Time.now.utc.iso8601», потому что есть много тестов, которые я должен изменить. Приложение выполняет множество запросов к другим API.
В любом случае, как настроить VCR на игнорирование совпадения тела для всех запросов «elasticsearch: 9200»?
Комментарии:
1. Вы можете использовать
timecop gem
для замораживания времени в определенный момент2. Или вы можете написать пользовательский механизм сопоставления, чтобы игнорировать
created_at
поле в теле ответа. Проверьтеthis article
3. Или вы можете выполнить сопоставление по другим атрибутам, чтобы игнорировать совпадение тела, поскольку оно меняется каждый раз. Проверьте
request-matching docs
. Как вы можете видеть, у вас есть множество вариантов на выбор4. Я решил проблему, имитируя метод «save» всех моих экземпляров «ElasticRepository» в тестовой среде с помощью «before (:all)». Спасибо за ответ.
Ответ №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