0
votes

I'm trying to write RSpec tests for an API.

Setup: To keep things consistent, we have a formatting function that takes the response and makes a nice JSON object so everything is consistent. E.g.- simplified for this example:

def format (status, message)
  {status: status,
   message: message}
end

This function is declared in a base controller that all the API controllers inherit from.

What I'd like: When I test an API controller I'd like to test that the controller gives me the expected result, but I don't want to test the actual format of the JSON response. As in, I want to check that the params passed to the format function are what I expect, but I don't want to check what that function actually returns. (I'm planning on testing that function in another test. I'd really like it if a change to the JSON format didn't affect every test for the API. If this isn't good practice feel free to let me know.)

My questions: Is there any way for me to access that format function from the base controller in the current API spec file? Or is there a good way for me to stub it out and get access to the params passed to it so I can check if they're correct?

Related: How to check for a JSON response using RSpec?

1

1 Answers

1
votes

Sounds like you're trying to do something like this in your controller spec:

let(:status) { function1(params_hash) }
let(:message { function2(params_hash) }
it "does something something" do
  model.should_receive(:format).with(status, message)
  get :action, params_hash
 end

Defining how status and message are calculated from params_hash is up to you. What I do is think of what are the various paths, and write a test for each one. Such as:

context "when id is missing in the params" do
 let(:status) { 404 }
 let(:message) { "Not found" }
 let(:params_hash) { {:id => nil} }

context "when id is correct" do
  let(:status) { 200 }
  let(:message) { "OK" }
  let(:params{hash) { {:id => 1 } }