1

I would like to have an ability of testing a remote 3d party API for endpoint responses, which is why I would like to write a bunch of local rspec tests and launch them periodically, to see if these endpoints are working as expected with no breaking changes. Since my application is highly dependent on this constantly changing API, I have little choice left but to automate my test.

At the moment I took a regular rspec API test code:

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 

The problem with this code is that Rspec is hitting the /api/endpoint url, instead of the full http://123.45.67.89/api/endpoint url. How can I change this behaviour?

1 Answer 1

1

RSpec's request specs are meant for testing your own application - by sending real HTTP requests. They are not intended for performing remote HTTP requests (even if it is possible monkey with the configuration to request other hosts than localhost).

Among other things a request spec will hit the API for every example - this will give you problems with rate limiting and throttling.

While you could try using a HTTP library like Net::HTTP, Httparty or Typhoeus in a request spec - what you really should do is rethink your methodology. Its a good idea to isolate the interaction between your application and external collaborators.

One way of doing this is by creating client classes that consume the remote API:

class ExampleAPIClient include HTTParty base_url 'example.com' format :json def get_some_data self.class.get('/foo') end end 

You can then test the remote endpoint by testing the client like a Plain Old Ruby Object:

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 

This will have the additional benefit of limiting exposure to change in your application as only a single component (the client) should fail if the remote api changes.

Other components which consume the client can stub out the remote interaction easily by stubbing the client.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.