Ruby on rails 从RSpec发送真正的JSON post请求

Ruby on rails 从RSpec发送真正的JSON post请求,ruby-on-rails,rspec,Ruby On Rails,Rspec,我希望能够为端点响应测试远程3d party API,这就是我希望编写一系列本地rspec测试并定期启动它们的原因,以查看这些端点是否按照预期工作,并且没有中断的更改。由于我的应用程序高度依赖于这个不断变化的API,我除了自动化测试外别无选择 目前,我接受了常规的rspec API测试代码: require "rails_helper" RSpec.describe "Remote request", type: :request do describe ".send request" d

我希望能够为端点响应测试远程3d party API,这就是我希望编写一系列本地rspec测试并定期启动它们的原因,以查看这些端点是否按照预期工作,并且没有中断的更改。由于我的应用程序高度依赖于这个不断变化的API,我除了自动化测试外别无选择

目前,我接受了常规的rspec API测试代码:

require "rails_helper"

RSpec.describe "Remote request", type: :request do
  describe ".send request" do
    it ".posts valid data" do
      post "http://123.45.67.89/api/endpoint",
        params: {
                  "job_request_id": 123456,
                  "data": "12345",
                  "app_secret": "12345",
                  "options": {
                     ...
                  }
                }

      expect(JSON.parse response.body).to include("message" => "success")
      expect(response).to have_http_status(200)
    end
  end
end

这段代码的问题是Rspec访问的是
/api/endpoint
url,而不是完整的
http://123.45.67.89/api/endpoint
url。如何改变这种行为?

RSpec的请求规范旨在通过发送真实的HTTP请求来测试您自己的应用程序。它们不用于执行远程HTTP请求(即使可以通过配置请求本地主机以外的其他主机)

除此之外,对于每个示例,请求规范都会影响API—这会给您带来速率限制和节流方面的问题

虽然您可以尝试使用HTTP库,如,或在请求规范中,但您真正应该做的是重新考虑您的方法。隔离应用程序和外部协作者之间的交互是个好主意

一种方法是创建使用远程API的客户端类:

class ExampleAPIClient
  include HTTParty
  base_url 'example.com'
  format :json

  def get_some_data
    self.class.get('/foo')
  end
end
然后,您可以通过像测试普通的旧Ruby对象一样测试客户端来测试远程端点:

require 'spec_helper'
RSpec.describe ExampleAPIClient do
  let(:client) { described_class.new }

  describe "#get_some_data" do
    let(:response) { client.get_some_data }
    it "should be successful" do
      expect(response.success?).to be_truthy
    end 
  end
end
这将有一个额外的好处,即限制应用程序中更改的暴露,因为如果远程api更改,只有单个组件(客户端)会失败

使用客户机的其他组件可以通过中断客户机轻松地中断远程交互