RSpec - Undefined method `key?'

匿名 (未验证) 提交于 2019-12-03 00:44:02

问题:

I'm trying to run a test for rendering templates and ran into the error:

undefined method `key?' for 1014:Fixnum 

The stub of my model's instance works as it should in my route tests but not so much here. What am I doing wrong?

describe RestaurantsController do   let(:restaurant) { FactoryGirl.build_stubbed(:restaurant) }    describe 'GET #show' do     before { get :show, restaurant.id }      it { should render_template('show') }   end end 

Full Error

 1) RestaurantsController GET #show       Failure/Error: before { get :show, restaurant.id }      NoMethodError:        undefined method `key?' for 1014:Fixnum      # /Library/Ruby/Gems/2.0.0/gems/actionpack-4.2.0/lib/action_controller/test_case.rb:744:in `html_format?'      # /Library/Ruby/Gems/2.0.0/gems/actionpack-4.2.0/lib/action_controller/test_case.rb:598:in `process'      # /Library/Ruby/Gems/2.0.0/gems/actionpack-4.2.0/lib/action_controller/test_case.rb:65:in `process'      # /Library/Ruby/Gems/2.0.0/gems/devise-3.5.1/lib/devise/test_helpers.rb:19:in `block in process'      # /Library/Ruby/Gems/2.0.0/gems/devise-3.5.1/lib/devise/test_helpers.rb:72:in `catch'      # /Library/Ruby/Gems/2.0.0/gems/devise-3.5.1/lib/devise/test_helpers.rb:72:in `_catch_warden'      # /Library/Ruby/Gems/2.0.0/gems/devise-3.5.1/lib/devise/test_helpers.rb:19:in `process'      # /Library/Ruby/Gems/2.0.0/gems/actionpack-4.2.0/lib/action_controller/test_case.rb:505:in `get'      # ./spec/controllers/restaurants_controller_spec.rb:15:in `block (3 levels) in <top (required)>' 

回答1:

get takes a action and hash of params (among other things). It will not implicitly take a model and turn it into { id: model.to_param }.

Instead you need to specify the parameters explicitly.

describe RestaurantsController do   let(:restaurant) { create(:restaurant) }    subject { response }    describe 'GET #show' do     before { get :show, id: restaurant }     it { should render_template('show') }   end end 

As @Зелёный has already mentioned you need to actually persist the record to the database to be able to use it in a controller spec.

To avoid the duplication issue and test ordering issues you should empty the database between each example. The database_cleaner gem is invaluable for that task.

Also if you need to create several records in the same spec you can use sequences in factory girl:

FactoryGirl.define do   factory :user do     email { |n| "test-#{n}@example.com" }   end end 

The gem ffaker is great for generating emails, usernames etc.

Added:

You can setup shortcuts for FactoryGirl by including its methods in your rails_helper:

RSpec.configure do |config|   # ...   config.include FactoryGirl::Syntax::Methods end 

This lets you use the FactoryGirl methods without typing the module name like so:

let(:restaurant) { create(:restaurant) } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!