继续在Rspec中获取未定义的方法错误

时间:2015-09-17 12:59:47

标签: ruby-on-rails rspec bdd

我有一个控制器动作'show',我正试图测试。控制器如下所示:

def show
  @contest = Contest.find(params[:contest_id])
  @my_entry = current_user.entries.where(contest_id: params[:contest_id]).sort_by { |entry| -entry.total_points}
  @points_per_player = @my_entry[0].points_per_player
  @total_points = @my_entry[0].total_points
  @opponents = @contest.entries.where.not(user_id: current_user.id).sort_by { |entry| -entry.total_points}
  @opponent_squad = Squad.find(@opponents[0].squad_id)
  @opponent_points = @opponents[0].points_per_player
end 

并且show动作的规范如下所示:

describe 'GET /show' do
   let!(:user) { create(:user) }
   let!(:squad_1) { create(:squad) }
   let!(:squad_2) { create(:squad) }
   let!(:contest) { create(:contest) }
   let!(:my_entry) { create(:entry, user_id: user.id, contest_id: contest.id) } 
   let!(:opponents) { [:squad_1, :squad_2] } 
   let!(:opponent_squad) { create(:squad) }

 before :each do
   sign_in user
   controller.instance_variable_set(:@opponent_squad, :squad )
   get :show, contest_id: contest.id
 end

 it "renders the show template" do
   (expect (response.status)).to eql(200)
   (expect (assigns(:opponents))).to eql([:squad_1, :squad_2])
   (expect (assigns(:opponent_squad))).to eql(:squad)
 end
end

Rspec不断抛出错误“未定义的方法`squad_id'为nil:NilClass”,我认为这是指show动作中的第二行,即:

@opponent_squad = Squad.find(@opponents[0].squad_id)

为什么会发生这种情况以及如何解决这个问题? (注意我对Rspec来说是非常新的)

2 个答案:

答案 0 :(得分:1)

我认为你的问题是这一行

 @opponents = @contest.entries.where.not(user_id: current_user.id).sort_by { |entry| -entry.total_points}

您正在查找user_id不是当前用户的所有条目。但在您的规范中,您创建的条目

  let!(:my_entry) { create(:entry, user_id: user.id, contest_id: contest.id) }

将user_id设置为当前用户,以便@opponents集合不会以任何结果结束。

然后你会寻找@oppone来获得一个值

 @opponent_squad = Squad.find(@opponents[0].squad_id)

获得例外。

我建议两件事。首先更新规范,以确保使用不同的user_id创建了该Entry类的实例,以便@opponent得到一个结果,然后用@ opponents.any检查控制器中的最后两行。所以,如果没有对手,你最终不会破坏事物。

答案 1 :(得分:0)

在最后的第三行,您使用的是current_user.id:

 @opponents = @contest.entries.where.not(user_id: current_user.id).sort_by { |entry| -entry.total_points}

但是在您的规范中,您使用curre_user

定义条目
let!(:my_entry) { create(:entry, user_id: user.id, contest_id: contest.id) } 

在这里,您正在搜索没有current_user.id的所有条目:

@opponents = @contest.entries.where.not(user_id: current_user.id).sort_by { |entry| -entry.total_points}

对于您的规范,您应该创建其他用户并为他创建一个条目。