First i read other posts of users with similiar problems, but couldnt come along where my mistake is. I wanted to start a test with RSpec on the following file:
dashboard_view_spec.rb:
require 'rails_helper'
RSpec.feature "Dashboard", type: :feature do
before(:each) do
@current_user = User.create!(email: "[email protected]", password: "xyz123")
sign_in_with(@current_user.email,@current_user.password)
end
#NAV BAR RSPEC TEST
scenario 'Home bar nav link present' do
visit "/"
expect(page).to have_text('Home')
end
scenario 'How it work nav bar link present' do
visit "/"
expect(page).to have_text('How it work')
end
scenario 'Support nav bar link present' do
visit "/"
expect(page).to have_text('Support')
end
end
On rails_helper.rb on the top:
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rake'
require 'spec_helper'
require 'rspec/rails'
require 'shoulda/matchers'
require 'capybara/rails'
require 'capybara/rspec'
require 'rspec/retry'
require 'devise'
Error message:
Failure/Error: require File.expand_path('../../config/environment', __FILE__)
NoMethodError:
undefined method `[]' for nil:NilClass
# ./config/initializers/devise.rb:258:in `block in <top (required)>'
# ./config/initializers/devise.rb:5:in `<top (required)>'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:4:in `require'
# ./spec/rails_helper.rb:4:in `<top (required)>'
# ./spec/views/dashboard_view_spec.rb:1:in `require'
# ./spec/views/dashboard_view_spec.rb:1:in `<top (required)>'
No examples found.
Randomized with seed 14549
Then the command i used on the terminal
bundle exec rspec spec/views/dashboard_view_spec.rb
After watching the documentation of testing with Devise i changed the code in dashboard_view_spec.rb and used to sign_in as a user and got the same error message.
Line 258 of devise.rb
config.omniauth :facebook, Rails.application.secrets.facebook[:key], Rails.application.secrets.facebook[:secret], scope: 'email', info_fields: 'email, name'
In the gemfile
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '~> 2.13'
gem 'selenium-webdriver'
gem 'rspec-rails', '~> 3.8'
gem 'factory_girl_rails'
gem 'faker'
gem 'database_cleaner'
end
and
group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
The problem is that you're missing a variable that your devise initializer expects to find, but only missing it in the test
environment. (not the development
environment)
The stack trace that you provided and line 258 from config/initializers/devise.rb
are all that are needed. First, let's look at the stack trace:
NoMethodError:
undefined method `[]' for nil:NilClass
# ./config/initializers/devise.rb:258:in `block in <top (required)>'
# ./config/initializers/devise.rb:5:in `<top (required)>'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:4:in `require'
# ./spec/rails_helper.rb:4:in `<top (required)>'
# ./spec/views/dashboard_view_spec.rb:1:in `require'
# ./spec/views/dashboard_view_spec.rb:1:in `<top (required)>'
Starting from the bottom up, we can see that the first line of your spec is what's causing the issue. If you follow the stack you'll see that it ends up in config/initializers/devise.rb:258
and is complaining that something making a []
method call isn't getting the expected object type in return, and is instead getting nil
in return.
Looking at line 258 you find:
config.omniauth :facebook, Rails.application.secrets.facebook[:key], Rails.application.secrets.facebook[:secret], scope: 'email', info_fields: 'email, name'
So you can see that there are two times that []
is called:
Rails.application.secrets.facebook[:key]
Rails.application.secrets.facebook[:secret]
What is expected is that calling Rails.application.secrets.facebook
will return an Enumerable
object (like an array or a hash) but instead it is returning nil
, and when it attempts to run nil[:key]
or nil[:secret]
it raises an exception because NilClass
is not an Enumerable
and does not have a []
method. You can test this yourself in the rails console
:
nil[:secret]
=> NoMethodError: undefined method `[]' for nil:NilClass
The solution is to ensure that calling Rails.application.secrets.facebook
returns the expected object type. The short answer is to edit config/secrets.yml
to ensure that the values you require for the test
environment are present.
I haven't worked with devise in a long time, but I assume that you can safely use the same values that you're using for the development
environment for the test
environment. You can read more about secrets()
elsewhere, but the basic template for config/secrets.yml
is as follows:
environment:
key: value
For example:
test:
my_secret_key: my_secret_value
It should be fairly straightforward to copy and paste the missing facebook
secrets into the test
environment. After making the change you can verify it worked:
$ RAILS_ENV=test rails console
Rails.application.secrets.facebook[:key]
=> <your key here>
If that worked, then run your spec with rspec
and it should successfully get past line 1. (assuming there are no other bugs or missing secrets)
I had very similar errors. Here's how I solved
Run rspec --backtrace
This could produce a lot of console output. Scroll right to the top, and start reading from the top. It will tell you the file your problem started in, and the line it happened on. Go to that file (and that line), and figure out what's missing.
In my case, it was actually a missing variable in credentials.yml
, but cases will vary. Like in the excellent answer by @anothermh, it's basically telling you something is missing, so you have to figure out what's missing and make sure you provide it.
Just got the same error, but when I ran bundle exec rake spec
instead of bundle exec rspec
it worked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With