首页 文章

Rspec错误 - NoMethodError:未定义的方法`空?'

提问于
浏览
0

我现在为控制器 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 回答

  • 1

    问题出在这里:

    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
    

    这是因为您无法直接访问控制器操作分配的实例变量 .

  • 4

    虽然模型中发生错误,但您的示例中也存在问题 .

    您似乎在假设因为 @search_result 是在控制器中定义的,所以可以在RSpec示例中直接访问它 . 事实并非如此 . @search_result 在示例中是 nil ,因为您尚未为其分配值 .

    但是,您可以通过RSpec assigns 方法访问控制器中的 @search_result 实例变量,如 assigns[:search_result] .

相关问题