【问题标题】:Rspec POST: create tests failing with undefined method `reject' for nil:NilClass?Rspec POST:使用未定义的方法'reject'为nil创建测试失败:NilClass?
【发布时间】:2015-12-23 23:03:56
【问题描述】:

我有一个带有 Rspec (3.1.0) 和 FactoryGirl (4.5.0) 的 Rails (4.1.8) 应用程序用于测试。我的控制器对创建后操作的测试失败并出现以下错误:

Failure/Error: post :create, { member_id: @member, fitness_goal: @fitness_goal_attributes }
 NoMethodError:
   undefined method `reject' for nil:NilClass

健身目标工厂:

FactoryGirl.define do

factory :fitness_goal do
association :goal_list
association :timeframe
start_date Date.current
end_date Date.current + 30
targets { [create(:target, outcome: "Lose Fat"), create(:target, outcome: "Reduce caloric intake by x%")] }
activities { [create(:activity, description: "Walk x steps a day"), create(:activity, description: "Climb x floors a day"), create(:activity, description: "Run x mile a day")] }   
association :member
association :trainer
notes 'This is a sample note.'
end
end

相关的FactoryGirl实例变量:

@fitness_goal_attributes = FactoryGirl.build(:fitness_goal).attributes

我在我的健身目标控制器的创建操作中使用了数组拒绝方法:

def create
  unless params[:fitness_goal].blank? && params[:activity_ids].blank? && params[:target_ids].blank?
  params[:fitness_goal][:activity_ids] = params[:fitness_goal][:activity_ids].reject{ |activity_ids| activity_ids.empty? }   
  params[:fitness_goal][:target_ids] = params[:fitness_goal][:target_ids].reject{ |target_ids| target_ids.empty? }      
  @fitness_goal = @member.fitness_goals.build(fitness_goal_params)

  if @fitness_goal.save 
    flash[:success] = "Fitness goal was successfully created."
    redirect_to member_fitness_goals_path(@member)
  else
    render 'new'
  end
 end
end

健身目标参数:

def fitness_goal_params
  params.require(:fitness_goal).permit(:goal_list_id, :timeframe_id, :start_date, :end_date, { target_ids: [] }, { activity_ids: [] }, :notes, :member_id, :trainer_id)
 end

**** 编辑 ****** binding.pry 的结果/更好的错误:

params[:fitness_goal][:activity_ids]
=> ["12", "10", "11"]

params[:fitness_goal][:target_ids]
=> ["1", "2"]

 params[:fitness_goal]
 => {"goal_list_id"=>"1", "timeframe_id"=>"2", "start_date"=>"2015-12-16", "end_date"=>"2016-01-15", "target_ids"=>["1", "2"], "activity_ids"=>["12", "10", "11"], "trainer_id"=>"", "notes"=>"testing"}

***** 编辑 *****

应用程序在开发和生产环境中按预期工作,但 Rspec 对 POST create 方法的所有测试都抛出错误。当我在数组上调用拒绝方法时,我无法弄清楚为什么 unless 语句没有充当“nil 守卫”。我做错了什么以及如何解决错误?

【问题讨论】:

  • 它来自 FitnessGoalsController.create 的第 3 行或第 4 行
  • @Andrew Williamson - 正如我在问题中提到的,我知道控制器中的错误来自哪里。我只是不知道如何解决它。
  • 一个好的开始是打印 params 变量,并确保 params[:fitness_goal][:activity_ids] 和 params[:fitness_goal][:target_ids] 都已定义
  • 使用 Pry / Better Errors,我可以确认两个参数变量都已定义。
  • 看起来确实不是。你能pry 你的 create 方法,运行测试,然后检查fitness_goal_params 并编辑你的问题以包含值吗?

标签: ruby ruby-on-rails-4 rspec factory-bot


【解决方案1】:

我发现您的代码中有 2 个错误可以解释:

  1. 当您可能打算使用 || 时,您使用 && 运算符

  2. 您检查了params[:activity_ids],但尝试使用params[:fitness_goal][:activity_ids]

所以你可以改变:

unless params[:fitness_goal].blank? && params[:activity_ids].blank? && params[:target_ids].blank?

作者:

unless params[:fitness_goal].blank? || params[:fitness_goal][:activity_ids].blank? || params[:fitness_goal][:target_ids].blank?

【讨论】:

  • 我更改了除非语句,但仍然收到错误:NoMethodError: undefined method `reject' for nil:NilClass
  • 是的,除非语句有另一个错误,我将编辑我的回复
  • 你也可以使用reject来简化你的代码!方法
  • 修改后的 unless 语句触发新错误:ActionView::MissingTemplate: Missing template Fitness_goals/create, application/create with {:locale=>[:en], :formats=>[:html] , :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}。在以下位置搜索:*“#<:rails::viewrendering::emptytemplatepathsetdecorator:0x00000005794758>”
  • 除非 contition 为真,否则您的情况。按照您的代码,在这种情况下,create 方法什么也不做;不调用渲染或重定向。如果你正确缩进你的代码,那会更清楚地显示你的东西。
猜你喜欢
  • 1970-01-01
  • 2014-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多