I'm now making Rspec for controller SearchController
. This controller do search record by sql with parameter which was got by "get" request. The controller is as follow.
class SearchController < ApplicationController
def index
if params[:category] == 'All'
@search_result = Item.find_by_sql("SELECT * FROM items WHERE name LIKE '%# {params[:name]}%'")
else
@search_result = Item.find_by_sql("SELECT * FROM items WHERE name LIKE '%#{params[:name]}%' AND category = '#{params[:category]}'")
end
if @search_result.empty? then
redirect_to main_app.root_path, notice: "No items found matching your search criteria ! Modify your search."
else
@search_result=@search_result.paginate(:page => params[:page],:per_page => 3)
end
end
end
Then I wrote simple Rspec test as follow. This test intends that at first the object item
is made to use in controller. Also the stub (Item.stub(:find_by_sql).and_return(item)
) is declared. Then do get :index
with parameter :category => 'All'
. My expect is that in the controller if params[:category] == 'All'
is passed and @search_result
is filled by object. (As I mentioned, the stub was already declared. Also object was already made. Then Item.find_by_sql(*****)
would return object which was already declared.)
require 'spec_helper'
describe SearchController do
let(:valid_session) { {} }
describe "" do
it "" do
item = Item.new(auction_id:'1',min_bid_price:'100.0')
item.save
Item.stub(:find_by_sql).and_return(item)
get :index, {:category => 'All'}, valid_session
@search_result.should_not be_empty
end
end
end
Then I ran Rspec and unfortunately got the error as follow. I think @search_result
could not be successfully filled with object, so "empty?" could not be called. However I have no idea about how to fix this. I already use many hours about this. I would like to have someone's help.
Failures:
1) SearchController
Failure/Error: get :index, {:category => 'All'}, valid_session
NoMethodError:
undefined method `empty?' for #<Item:0x523c980>
# ./app/controllers/search_controller.rb:9:in `index'
# ./spec/controllers/search_controller_spec.rb:13:in `block (3 levels) in <top (required)>'
Finished in 0.25 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/search_controller_spec.rb:8 # SearchController
Randomized with seed 50151
The problem is here:
Item.stub(:find_by_sql).and_return(item)
You are stubbing find_by_sql and returning a single item instead of a collection of items. The simple fix is to wrap it in an array:
Item.stub(:find_by_sql).and_return [item]
Note that this will only work if Array is modified to support paginate
(will_paginate will do this if you require the `will_paginate/array' library).
Aside from this, as @PeterAlfvin has mentioned, you have a mistake near the end of your spec:
@search_result.should_not be_empty
Should actually be written as:
assigns(:search_result).should_not be_empty
This is because you can't access instance variables assigned by your controller action directly.