Reputation: 29
Summary: I am new to Ruby on Rails. Was doing a class assignment for TDD using rspec for the edit feature. I encountered this error:
Failure/Error: visit "/categories/#{category.id}/edit" NoMethodError: undefined method `id' for nil:NilClass
What I have done is to define the edit and update methods in the CategoriesController but error persists.
Please refer to codes below. Thankful for your guidance.
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
Upvotes: 0
Views: 781
Reputation: 1309
Rails tests are fully independent (in theory) and don't maintain data between tests. So, if you create a Category in one test and then try to access it in another test (as you're doing here), it won't work. It works this way so that you don't get cascading failures but can test things discretely. Rails provides various methods to create the data you're then going to test. Fixtures are the simplest, but there are gems like FactoryGirl you can use, too.
The easiest solution to your problem here is to combine these two test methods (it 'creates category, saves and shows newly created category'
and it 'edits category, saves and shows edited category'
) into a single method that first creates and then edits the Category record.
Better would be to keep them separate (because your test suite will soon become large and complex, and you'll need to separate them), and to use fixtures to set up your records before testing.
Finally, when you're writing tests, don't forget to write tests that capture failure - your code should refuse to create or edit the record if the data provided isn't valid, for example.
Upvotes: 1