Заглушка запроса Фарадея с Webmock - нужна помощь

Мне нужна помощь, чтобы заглушить запрос с помощью драгоценного камня Фарадея. я делаю этот запрос

URL='https://secure.snd.payu.com//pl/standard/user/oauth/authorize'.freeze
url_encoded = 'grant_type=client_credentials' \
      + "&client_id=#{ENV['client_id'}" \
      + "&client_secret=#{ENV['client_secret'}"

connection = Faraday.new do |con|
  con.response :oj, content_type: /\bjson$/
  con.adapter Faraday.default_adapter
end

connection.post(URL, url_encoded)

который выводит

#<Faraday::Response:0x00000000016ff620 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:post @body={"access_token"=>"00a4e007-220b-4119-aae8-3cb93bb36066", "token_type"=>"bearer", "expires_in"=>43199, "grant_type"=>"client_credentials"} @url=#<URI::HTTPS https://secure.snd.payu.com/pl/standard/user/oauth/authorize> @request=#<Faraday::RequestOptions (empty)> @request_headers={"User-Agent"=>"Faraday v0.17.1"} @ssl=#<Faraday::SSLOptions verify=true> @response=#<Faraday::Response:0x00000000016ff620 ...> @response_headers={"set-cookie"=>"cookieFingerprint=70a4a8d1-7b05-4cb9-9d5c-5ad12e966586; Expires=Fri, 25-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly, payu_persistent=mobile_agent-false#; Expires=Sun, 20-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly", "correlation-id"=>"0A4DC804-62FD_AC11000F-0050_5E047DD5_8A0178-0015", "cache-control"=>"no-store, no-cache, no-store, must-revalidate", "pragma"=>"no-cache, no-cache", "content-type"=>"application/json;charset=UTF-8", "transfer-encoding"=>"chunked", "date"=>"Thu, 26 Dec 2019 09:31:01 GMT", "server"=>"Apache", "x-content-type-options"=>"nosniff", "x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "expires"=>"0", "connection"=>"close"} @status=200 @reason_phrase="OK">>
 => #<Faraday::Response:0x00000000016ff620 @on_complete_callbacks=[], @env=#<Faraday::Env @method=:post @body={"access_token"=>"00a4e007-220b-4119-aae8-3cb93bb36066", "token_type"=>"bearer", "expires_in"=>43199, "grant_type"=>"client_credentials"} @url=#<URI::HTTPS https://secure.snd.payu.com/pl/standard/user/oauth/authorize> @request=#<Faraday::RequestOptions (empty)> @request_headers={"User-Agent"=>"Faraday v0.17.1"} @ssl=#<Faraday::SSLOptions verify=true> @response=#<Faraday::Response:0x00000000016ff620 ...> @response_headers={"set-cookie"=>"cookieFingerprint=70a4a8d1-7b05-4cb9-9d5c-5ad12e966586; Expires=Fri, 25-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly, payu_persistent=mobile_agent-false#; Expires=Sun, 20-Dec-2020 09:31:02 GMT; Path=/; ; HttpOnly", "correlation-id"=>"0A4DC804-62FD_AC11000F-0050_5E047DD5_8A0178-0015", "cache-control"=>"no-store, no-cache, no-store, must-revalidate", "pragma"=>"no-cache, no-cache", "content-type"=>"application/json;charset=UTF-8", "transfer-encoding"=>"chunked", "date"=>"Thu, 26 Dec 2019 09:31:01 GMT", "server"=>"Apache", "x-content-type-options"=>"nosniff", "x-frame-options"=>"SAMEORIGIN", "x-xss-protection"=>"1; mode=block", "expires"=>"0", "connection"=>"close"} @status=200 @reason_phrase="OK">> 

Я заглушаю этот запрос следующим образом

stub_request(:post, 'https://secure.payu.com/pl/standard/user/oauth/authorize')
  .with(
         body: 'grant_type=client_credentials&client_id=10&client_secret=absdef',
         headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
       )
  .to_return(status: 200, body: '{"status":"SUCCESS"}')

и я получаю эту ошибку.

WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled. Unregistered request: POST https://secure.payu.com/pl/standard/user/oauth/authorize with body 'grant_type=client_credentials&client_id=12345&client_secret=secret_client' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Faraday v0.17.1'}

       You can stub this request with the following snippet:

       stub_request(:post, "https://secure.payu.com/pl/standard/user/oauth/authorize").
         with(
           body: "grant_type=client_credentials&client_id=12345&client_secret=secret_client",
           headers: {
          'Accept'=>'*/*',
          'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
          'User-Agent'=>'Faraday v0.17.1'
           }).
         to_return(status: 200, body: "", headers: {})

       registered request stubs:

       stub_request(:post, "https://secure.payu.com/pl/standard/user/oauth/authorize").
         with(
           body: "grant_type=client_credentials&client_id=10&client_secret=absdef",
           headers: {
          'Content-Type'=>'application/x-www-form-urlencoded'
           })

Я не знаю, почему он жалуется на заголовки. Из того, что я вижу в выводе выше, Фарадей не отправляет заголовки, на которые указывает Webmock. У вас есть идеи, как это решить?


person jedi    schedule 26.12.2019    source источник
comment
Не похоже, чтобы тело и заголовки соответствовали вашим ожиданиям и тому, что происходит на самом деле. Сравните их, например, заголовок Content-Type на самом деле не отправляется, а тело отличается.   -  person max pleaner    schedule 26.12.2019
comment
Единственная разница должна заключаться в заголовках, поскольку я не отправляю тело. Я не вижу, чтобы эти заголовки отправлялись, когда я делаю запрос локально   -  person jedi    schedule 26.12.2019
comment
Там, где говорится, что вы можете заглушить этот запрос следующим фрагментом, следующий stub_request вызов является тем, который фактически выполняется. Итак, я подвергаю сомнению ваше заявление о том, что вы не отправляете тело. Это должно быть добавлено каким-то образом.   -  person max pleaner    schedule 26.12.2019
comment
Вы правы, @maxpleaner Я ошибался, я отправляю тело, но единственное, что я отправляю, это то, что вы видите в коде. Должен ли я считать, что остальные отправляются Фарадеем по умолчанию?   -  person jedi    schedule 26.12.2019


Ответы (1)


Нужно ли заглушить запрос или вам просто нужно издеваться над ответом? Когда я пишу спецификации клиента Faraday, я обычно делаю что-то вроде этого:

let(:client) {
  instance_double(Faraday::Connection, post: faraday_response)
}
let(:faraday_response) { instance_double(Faraday::Response, body: body) }
let(:body)             {
  {
    'some_key' => 'some_value'
  }
}

before do
  allow(Faraday).to receive(:new) { client } 
  allow(client).to receive(:post) { faraday_response }
end

it 'redirects to the place' do
  request
  expect(response).to redirect_to(some_path)
end

it 'changes the stuff' do
  expect { request }.to change { 
    something.reload.attribute 
  }.from(thing1).to(thing2)
end

person Allison    schedule 27.12.2019
comment
Сначала я написал спецификации так, но подумал, что было бы неплохо заглушить и запросы. - person jedi; 28.12.2019
comment
@jedi Я вижу. Я понимаю желание просто выяснить, как работают альтернативные подходы. Если используемый вами запрос API будет использоваться в нескольких спецификациях, я предлагаю настроить что-то вроде VCR (rubyguides.com/2018/12/ruby-vcr-gem), которые помогут упростить любые спецификации, необходимые для выполнения того же запроса. - person Allison; 30.12.2019
comment
В конце концов я придерживался своего первоначального плана. Спасибо за подсказку! Обязательно попробую!!! С Новым Годом! - person jedi; 31.12.2019
comment
@Эллисон довольно умна! - person Jacka; 01.06.2020