Question

I'm trying to test the following with RSpec and FactoryGirl:

describe 'GET #show' do
    it "assigns the requested dish to @dishes" do
        dish = create(:dish)
        get :show, id: dish
        expect(assigns(:dish)).to eq dish
    end
end

FactoryGirl.define do
  factory :dish, :class => 'Dish' do |f|
    f.name "TestDish"
    f.header "TestHeader"
    f.author_id "1"
    f.avatar { File.open("spec/support/sample_photo.jpg")}
  end

  factory :invalid_dish do |f|
    f.name nil
  end
end

But I am getting the following error:

  1) DishesController GET #show assigns the requested dish to @dishes
     Failure/Error: get :show, id: dish
     ActionView::Template::Error:
       undefined method `full_name' for nil:NilClass
     # ./app/views/dishes/show.html.erb:3:in `_app_views_dishes_show_html_erb___4424609358762382481_2199208220'
     # ./app/controllers/dishes_controller.rb:16:in `block (2 levels) in show'
     # ./app/controllers/dishes_controller.rb:15:in `show'
     # ./spec/controllers/dishes_controller_spec.rb:14:in `block (3 levels) in <top (required)>'

I believe the problems lies in my show view with this line:

<p><%= @dish.author.full_name %></p>

In the author.rb model I've defined the following:

def full_name
        full_name = first_name + " " + last_name
    end

my dish.rb model belongs_to :author and my author.rb model has_many :dishes

I've tried to google a bit around, but can't seem to find any specific answer to my issue, apart from this thread RSpec: ActionView::Template::Error: undefined method `full_name' for nil:NilClass but I don't really understand what's going on there.

Let me know if any more info is needed!

Thanks in advance Chris

Was it helpful?

Solution

You get undefined method 'full_name' for nil:NilClass error because in @dish.author.full_name, @dish.author is nil i.e., the dish record doesn't have a matching author record.

What you need is to setup the factories such that when you create a dish its associated record also gets created :

FactoryGirl.define do
  factory :dish, :class => 'Dish' do |f|
    f.name "TestDish"
    f.header "TestHeader"
    f.avatar { File.open("spec/support/sample_photo.jpg")}
    ## f.author_id "1"  Remove this line
    association :author, factory: :assoc_author  ## set association
  end

  factory :assoc_author, :class => 'Author' do |f|
    ## assign fields
    f.first_name "John"
    f.last_name "Doe" 
  end
  ## ...
end

This way when you call create(:dish), it will create a record in dishes table plus an associated record in authors table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top