Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Message: Failure/Error: require File.expand_path('../../config/environment', __FILE__)

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
like image 755
James Rich Avatar asked Oct 19 '18 15:10

James Rich


3 Answers

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)

like image 200
anothermh Avatar answered Nov 18 '22 06:11

anothermh


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.

like image 3
stevec Avatar answered Nov 18 '22 06:11

stevec


Just got the same error, but when I ran bundle exec rake spec instead of bundle exec rspec it worked.

like image 2
lafeber Avatar answered Nov 18 '22 04:11

lafeber