Baub
Baub

Reputation: 5054

What belongs in a controller spec and what belongs in a request spec?

Using Rspec, I am trying to create a controller spec for my API, as well as a request spec. The problem is I don't understand what part of the test goes in each spec.

For simplicity, let's say my controller looks like follows:

class Api::V1::ItemsController < ApplicationController
  def index
    if params[:user_id]
      user = User.find(params[:user_id])
      @items = user.items
    else
      @items = Item.all
    end
  end
end

It uses RABL to render the response.

For a controller as simple as this, what does the controller spec look like? What does the request spec look like? At what point to I verify that the API response JSON is what I expect? etc.

Upvotes: 0

Views: 113

Answers (2)

Jim Stewart
Jim Stewart

Reputation: 17343

For the controller spec, I'd write tests like this:

it "renders with a user_id" do
  get :index, id: @user.id
  assigns(:items).should == @user.items
  response.should be_success
  response.should render_template("index")
end

One for the user_id path, and one without. I leave setting up @user to you; you can use fixtures, or FactoryGirl, instantiate one in a before block, or just stub/mock it all out. It's good to avoid hitting the database at all if you can. That can be a little trickier with things like Item.all and associations, which are harder to wire up without either stubbing or persisting to the test DB. Mocking and stubbing makes it easy, but also makes your tests a bit more brittle should the models change.

For the request spec, I'd create real DB objects and do something like this, using Capybara:

it "lists all items without a user_id" do
  visit foo_path
  current_path.should == foo_path
  page.should have_content(item1.name)
  page.should have_content(item2.name)
end

..and similar for the path with user_id. Without knowing your data and how you're rendering it, I can't be more specific. If you're using JSON, you should check the entire JSON response here. I wouldn't check the JSON response in the controller spec, though; the controller's job is just to shuffle the data to the right view. You can test the view in isolation too, and then test the whole end-to-end scenario in your request spec.

Upvotes: 2

jvnill
jvnill

Reputation: 29599

For the controller spec, you'd set up mocks that will handle the authentication of the request. You'd only want to test that if params[:user_id] is passed, then @items is set to the user items, and if not, then all items.

For the request spec, you will simply include some test to verify the process of authentication.

If you ask me, I'll verify the api response as a json in both tests.

Upvotes: 1

Related Questions