RSpec未定义方法`full_name'为零:NilClass

时间:2014-04-06 14:02:57

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

我正在尝试使用RSpec和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

但是我收到以下错误:

  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)>'

我认为问题出在我的展示视图中:

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

在author.rb模型中,我定义了以下内容:

def full_name
        full_name = first_name + " " + last_name
    end

我的dish.rb模型belongs_to :author和我的author.rb模型has_many :dishes

我试图谷歌一点,但似乎找不到我的问题的任何具体答案,除了这个线程RSpec: ActionView::Template::Error: undefined method `full_name' for nil:NilClass,但我真的不明白那里发生了什么。

如果需要更多信息,请告诉我们!

提前致谢 克里斯

1 个答案:

答案 0 :(得分:0)

您收到undefined method 'full_name' for nil:NilClass错误,因为在@dish.author.full_name中,@dish.author nil ,即菜肴记录没有匹配的作者记录。

您需要的是设置工厂,以便在创建菜肴时也会创建相关记录:

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

这样当你调用create(:dish)时,它会在dishes表中创建一条记录,并在authors表中创建一个相关记录。