【问题标题】:Keep getting undefined method error in Rspec在 Rspec 中不断出现未定义的方法错误
【发布时间】:2015-09-17 12:59:46
【问题描述】:

我有一个控制器动作“显示”,我正在尝试测试它。控制器如下所示:

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 不断抛出错误“undefined method `squad_id' for nil:NilClass”,我认为这是指显示操作中的倒数第二行,即:

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

任何想法为什么会发生这种情况以及如何解决它? (注意我对 Rspec 非常陌生)

【问题讨论】:

    标签: ruby-on-rails rspec bdd


    【解决方案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 集合就不会得到任何结果。

    然后你寻找@opponents 有一个值

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

    并得到一个例外。

    我建议两件事。首先更新规范以确保已使用不同的 user_id 创建了该 Entry 类的实例,以便 @opponents 获得结果,然后将最后两行包装在控制器中并检查 @opponents.any?这样你就不会在没有对手的情况下破坏东西。

    【讨论】:

      【解决方案2】:

      在最后第三行你正在使用 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}
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 2022-06-15
        • 1970-01-01
        相关资源
        最近更新 更多