【问题标题】:Got a NoMethodError: undefined method `id' for nil:NilClass得到一个 NoMethodError: undefined method `id' for nil:NilClass
【发布时间】:2021-07-28 08:55:09
【问题描述】:

总结:我是 Ruby on Rails 的新手。正在使用 rspec 为编辑功能做 TDD 的课堂作业。我遇到了这个错误:

失败/错误:访问“/categories/#{category.id}/edit” NoMethodError:未定义方法 `id' for nil:NilClass

我所做的是在 CategoriesController 中定义编辑和更新方法,但错误仍然存​​在。

请参考以下代码。感谢您的指导。

edit_category_spec.rb:


RSpec.describe 'EditCategories', type: :system do
  before do
    driven_by(:rack_test)
  end

  it 'creates category, saves and shows newly created category' do
    # visit root route
    visit '/'
    #click create category link
    click_link 'Create Category'
    #visit categories/new page
    visit '/categories/new'
    #fill in form with required info
    fill_in 'Name', with: 'This is a category'
    #click submit button
    click_button 'Create Category'
    #expect page to have the content submitted
    expect(page).to have_content('This is a category')
  end

  it 'edits category, saves and shows edited category' do
    category = Category.order("id").last
    visit "/categories/#{category.id}/edit"
    fill_in 'Name', with: 'This is a category edited'
    click_button 'Create Category'
    expect(page).to have_content('This is a category edited')
  end
end  ```


categories_controller.rb
```class CategoriesController < ApplicationController
  def index
  end

  def show
    @category = Category.find(params[:id])
  end

  def new
    @category = Category.new
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      redirect_to @category
    else
      render :new
    end
  end

  def edit
    @category = Category.find(params[:id])
  end

  def update
    @category = Category.find(params[:id])
    if @category.save
      redirect_to @category
    else
      render :edit
    end
  end

  private

  def category_params
    params.require(:category).permit(:name)
  end
end

【问题讨论】:

  • category = Category.order("id").lastcategory 变量上设置nil,因为可能不存在类别
  • 感谢您的洞察力。

标签: ruby-on-rails rspec-rails


【解决方案1】:

Rails 测试是完全独立的(理论上),不会在测试之间维护数据。因此,如果您在一个测试中创建一个类别,然后尝试在另一个测试中访问它(就像您在此处所做的那样),它将不起作用。它以这种方式工作,这样您就不会遇到级联故障,而是可以离散地测试事物。 Rails 提供了各种方法来创建您将要测试的数据。 Fixtures 是最简单的,但您也可以使用像 FactoryGirl 这样的 gem。

解决您的问题的最简单方法是将这两种测试方法(it 'creates category, saves and shows newly created category'it 'edits category, saves and shows edited category')组合成一个方法,首先创建然后编辑类别记录。

最好将它们分开(因为您的测试套件很快就会变得庞大而复杂,您需要将它们分开),并在测试之前使用夹具来设置您的记录。

最后,当您编写测试时,不要忘记编写捕获失败的测试 - 例如,如果提供的数据无效,您的代码应该拒绝创建或编辑记录。

【讨论】:

  • 非常感谢您提供详细解释的答案。很有帮助。
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 2016-08-13
  • 1970-01-01
  • 2016-01-02
  • 2012-08-08
  • 2014-09-05
  • 1970-01-01
  • 2020-09-24
相关资源
最近更新 更多