Rspec - RuntimeError: Called id for nil, 这会错误地为 4 [英] Rspec - RuntimeError: Called id for nil, which would mistakenly be 4

查看:26
本文介绍了Rspec - RuntimeError: Called id for nil, 这会错误地为 4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在对 ItemsControllercreate 操作进行 Rspec 测试,但是我遇到了错误问题.(有ItemAuctionBidUser)

I'm now making Rspec test for create action of ItemsController, however I'm in trouble about the error. (There are models as Item, Auction, Bid, User)

create 方法如下

 # POST /items
 # POST /items.json
 def create
   @item = Item.new(params[:item])
   @item.user_id = current_user.id

   respond_to do |format|
     if @item.save
       format.html { redirect_to @item, notice: 'Item was successfully created.' }
       format.json { render json: @item, status: :created, location: @item }
     else
       format.html { render action: "new" }
       format.json { render json: @item.errors, status: :unprocessable_entity }
     end
   end
   @elapsed_seconds =(((params[:item][:days].to_i * 24)+params[:item][:hours].to_i)*60+params[:item][:minutes].to_i)*60
   @auction = Auction.create(:item_id => @item.id, :highest_bid_id => 0, :exp_time =>             
   @item.created_at+ @elapsed_seconds.seconds, :suspend => 0, :user_id => @current_user.id, :extend_bit => 0 )
   @item.update_attributes(:auction_id => @auction.id)
   @item_id = @item.id
   @auction_id = @auction.id
   @t1 = Thread.new{
     @timer = Timers.new
     @bid_timer = @timer.after(@elapsed_seconds){
       if Auction.find_by_id(@auction_id).suspend != 1
          buy
       end
     }
   @timer.wait
   }

end

def buy
  if Auction.find_by_id(@auction_id).extend_bit == 1
    extendtimer
  else
    if Auction.find_by_id(@auction_id).highest_bid_id != 0
      Item.find_by_auction_id(@auction_id).update_attributes(:sold => 1, :sold_to => Bid.find_by_id(Auction.find_by_id(@auction_id).highest_bid_id).user_id )
      MyMailer.auction_winner_email(Auction.find_by_id(@auction_id)).deliver
    else
      Item.find_by_auction_id(@auction_id).update_attributes(:sold => 0, :sold_to => 0 )
      MyMailer.no_bids_email(Auction.find_by_id(@auction_id)).deliver
    end
    @t1.join
  end
end

def extendtimer
    Auction.find_by_id(@auction_id).update_attributes(:extend_bit => 0)
    @exp = Auction.find_by_id(@auction_id).exp_time + 2.minutes
    Auction.find_by_id(@auction_id).update_attributes(:exp_time => @exp)
    @min = Item.find_by_id(@item_id).minutes + 2
    Item.find_by_id(@item_id).update_attributes(:minutes => @min)
    @timer2 = Timers.new
    @extend_timer = @timer2.after(120){ buy }
    @timer2.wait
end

我的 Rspec 如下.此测试旨在首先使用对象(例如 current_userauction、item).然后还声明存根.(例如代码>Auction.stub(:find_by_id).and_return(auction)`)

And my Rspec is as follow. This test intends that at first objects were made to use (such as current_user, auction, "item). Then also stubs are declared. (such asAuction.stub(:find_by_id).and_return(auction)`)

require 'spec_helper'

describe ItemsController do

  let(:valid_session) { {} }

  describe "POST create" do
    it "" do
      #declare the objects and stubs
      current_user = User.new(id:'1')
      current_user.save
      auction = Auction.new(id:'1',highest_bid_id:'1', extend_bit:'1')
      auction.save
      Auction.stub(:find_by_id).and_return(auction)
      bid = Bid.new(auction_id:'1',amount:'150.0')
      bid.save
      Bid.stub(:find_by_id).and_return(bid)
      item = Item.new(id:'1',auction_id:'1',min_bid_price:'100.0')
      item.save
      Item.stub(:find_by_id).and_return(item)

      #POST create 
      post :create, {:item => {'id' => '2','days'=>'1','hours'=>'1','minutes'=>'1'}}

      response.should redirect_to(@item)
      flash[:notice].should eql("Item was successfully created.")


    end
  end
end

不幸的是,我运行了 Rspec,出现如下错误.我认为 @item = Item.new(params[:item]) 无法成功创建控制器中的 @item,因此可能会发生此错误.但是我找不到如何修复.我已经为此花费了很多时间.我想得到某人的帮助.

Unfortunately I ran Rspec, I got the error as follow. I think @item in controller could not be successfully created by @item = Item.new(params[:item]), so this error might be happen. However I couldn't find how to fix. I already used many hours for this. I would like to have someone's help.

失败:

1) ItemsController POST create
 Failure/Error: post :create, {:item => {'id' => '2','days'=>'1','hours'=>'1','minutes'=>'1'}}
 RuntimeError:
   Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
 # ./app/controllers/items_controller.rb:72:in `create'
 # ./spec/controllers/items_controller_spec.rb:19:in `block (3 levels) in <top (required)>'

 Finished in 0.637 seconds 1 example, 1 failure

 Failed examples:

  rspec ./spec/controllers/items_controller_spec.rb:11 # ItemsController POST create

  Randomized with seed 33483  

推荐答案

由于没有人登录,current_user 方法返回 nil.在规范中设置局部变量 current_user 对此无济于事.相反,您可以定义 ApplicationController#current_user= 方法:

Since no one is logged in, current_user method returns nil. Setting local variable current_user in spec won't help for that. Instead, you could define ApplicationController#current_user= method:

def current_user=(user)
  @current_user ||= user
end

并在您的规范中调用它:

and call it in your specs:

controller.current_user = current_user

这篇关于Rspec - RuntimeError: Called id for nil, 这会错误地为 4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆