我现在为控制器 SearchController
制作Rspec . 该控制器通过带有"get"请求获得的参数的sql搜索记录 . 控制器如下 .
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)
) . 然后使用参数 :category => 'All'
执行 get :index
. 我的期望是在控制器 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
无法成功填充对象,因此无法调用"empty?" . 但是我不知道如何解决这个问题 . 我已经用了好几个小时了 . 我想得到别人的帮助 .
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
2 回答
问题出在这里:
您正在查找find_by_sql并返回单个项而不是项集合 . 简单的解决方法是将其包装在一个数组中:
请注意,这只有在修改Array以支持
paginate
时才会起作用(如果需要`will_paginate / array'库,will_paginate将执行此操作) .除此之外,正如@PeterAlfvin所提到的那样,在规范结束时你有一个错误:
应该写成:
这是因为您无法直接访问控制器操作分配的实例变量 .
虽然模型中发生错误,但您的示例中也存在问题 .
您似乎在假设因为
@search_result
是在控制器中定义的,所以可以在RSpec示例中直接访问它 . 事实并非如此 .@search_result
在示例中是nil
,因为您尚未为其分配值 .但是,您可以通过RSpec
assigns
方法访问控制器中的@search_result
实例变量,如assigns[:search_result]
.