kavin
kavin

Reputation: 3

I need help to write the rspec test in rails

I have a items_controller.rb

  def get_serialized_copy_of_item
    @item= Item.find_by_id(params[:id]) 
    if @item.nil?
      head :no_content
    else
      respond_to do |format|
      serialized_item = @item.as_json(include: [:test1, :test2, :test3, :test4])
      format.html
      format.json { render json: serialized_item }  
      end
    end
  end

routes.rb

namespace :items do
  get '/get_serialized_copy_of_item/:id', to:'items#get_serialized_copy_of_item'
end

I want to write a rspec test

  1. submit incorrect item id and make sure that 204 is returned

I have done

require 'spec_helper'

describe Items::ItemsController do
  describe "GET items#get_serialized_copy_of_item" do
     it "renders 204 status code" do
      get "/items/get_serialized_copy_of_item/dfsdf"
      expect(last_response.status).to eq(204)
    end
  end
end

Error: I am getting routing error

F

Failures:

  1) Items::ItemsController GET items#item renders 204 status code
     Failure/Error: get "/items/get_serialized_copy_of_item/dfsdf"
     ActionController::RoutingError:
       No route matches {:controller=>"items/items", :action=>"/items/get_serialized_copy_of_item/dfsdf"}
     # ./spec/controllers/items/items_controller_spec.rb:6:in `block (3 levels) in <top (required)>'

Finished in 0.01576 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/items/items_controller_spec.rb:5 # Items::itemsController GET items#item renders 204 status code

bundle exec rake routes

                                       GET    `items/get_serialized_copy_of_item/:id(.:format)                            items/items#get_serialized_copy_of_item`

Thanks

Upvotes: 0

Views: 88

Answers (2)

sixty4bit
sixty4bit

Reputation: 7926

RSpec assumes the controller name from the name of the test. Note the example in this doc:

describe WidgetsController do
  describe "GET index" do
    it "has a 200 status code" do
      get :index
      response.code.should eq("200")
    end
  end
end

Here RSpec already knows the widgets part of the path because of describe WidgetsController, so the get method only takes :index as an argument.

To translate that to your case:

describe Items::ItemsController do
  describe "GET get_serialized_copy_of_item" do
     it "renders 204 status code" do
      get :get_serialized_copy_of_item, id: 'sdf'

      expect(response.status).to eq(204)
    end
  end
end
  1. You only need to pass the name of the action to the get() method, not the entire path.
  2. You need to include the :id param as a second argument to get()
  3. It seems like namespace is the wrong way to do the routing here. Try changing your route definitions to this:
resources :items do 
  member do 
    get :get_serialized_copy
  end
end

This will generate the following route:

➜  bundle exec rake routes
   Prefix Verb   URI Pattern     

    Controller#Action
get_serialized_copy_item GET    /items/:id/get_serialized_copy(.:format) items#get_serialized_copy

For this you want to have your ItemsController in app/controllers/items_controller.rb

Upvotes: 3

tywhang
tywhang

Reputation: 309

From what I can see there isn't any nesting.

If so, you should be calling ItemsController instead of Items::ItemsController.

items_controller_spec:

require 'spec_helper'

describe ItemsController do
  describe "GET #get_serialized_copy_of_item" do
     it "renders 204 status code" do
      get "/items/get_serialized_copy_of_item/dfsdf"
      expect(last_response.status).to eq(204)
    end
  end
end

Upvotes: 0

Related Questions