我现在为控制器SearchController
制作Rspec。该控制器通过sql搜索记录,参数由“get”请求获得。控制器如下。
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
然后我写了简单的Rspec测试如下。此测试旨在首先使对象item
在控制器中使用。还声明了存根(Item.stub(:find_by_sql).and_return(item)
)。然后使用参数get :index
执行:category => 'All'
。我希望在控制器if params[:category] == 'All'
中传递,@search_result
由对象填充。 (正如我所提到的,已经声明了存根。还有对象已经完成。然后Item.find_by_sql(*****)
将返回已经声明的对象。)
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
然后我跑了Rspec,不幸的是得到了如下错误。我认为@search_result
无法成功填充对象,所以“空”?无法调用。但是我不知道如何解决这个问题。我已经用了好几个小时了。我想得到别人的帮助。
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
答案 0 :(得分:4)
问题在于:
Item.stub(:find_by_sql).and_return(item)
您正在查找find_by_sql并返回单个项而不是项集合。简单的解决方法是将其包装在一个数组中:
Item.stub(:find_by_sql).and_return [item]
请注意,只有在修改Array以支持paginate
时才会这样做(如果需要`will_paginate / array'库,will_paginate会执行此操作。)
除此之外,正如@PeterAlfvin所提到的,你的规范即将结束时出现错误:
@search_result.should_not be_empty
实际上应该写成:
assigns(:search_result).should_not be_empty
这是因为您无法直接访问控制器操作分配的实例变量。
答案 1 :(得分:1)
虽然模型中出现错误,但您的示例中也存在问题。
您似乎在假设因为@search_result
是在控制器中定义的,所以可以在RSpec示例中直接访问它。事实并非如此。 <{1}}在示例中为@search_result
,因为您尚未为其指定值。
可以通过RSpec nil
方法访问控制器中的@search_result
实例变量,如assigns
。