消息:失败/错误:要求文件扩展路径('../../config/environment',__FILE__)

11

我先阅读了其他用户发布的与我的问题类似的帖子,但是没有找到解决方法。我想要在以下文件中使用RSpec进行测试:

dashboard_view_spec.rb:

require 'rails_helper'

RSpec.feature "Dashboard", type: :feature do 
before(:each) do
@current_user = User.create!(email: "xyz@xyz.com", 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

在rails_helper.rb文件的顶部:

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

错误信息:

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

然后在终端上使用的命令

 bundle exec rspec spec/views/dashboard_view_spec.rb

在观看使用 Devise 进行测试的文档后,我修改了 dashboard_view_spec.rb 中的代码并使用 sign_in 作为 user,但是得到了相同的错误信息。

devise.rb 的第 258 行。

 config.omniauth :facebook, Rails.application.secrets.facebook[:key],  Rails.application.secrets.facebook[:secret], scope: 'email', info_fields: 'email, name'

在 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

你能添加完整的堆栈跟踪和执行的命令吗? - R. Sierra
我添加了该指令。错误输出中没有堆栈跟踪。我截取了终端的错误信息。 - James Rich
我已经修改了它。希望现在更好了。感谢您的提示! - James Rich
你仍然没有发布 config/initializers/devise.rb:258 中的内容。错误信息非常简单:第 258 行上的某些东西正试图对一个对象执行 [],它期望该对象是一个 Array,但实际上是 nil。找到该对象,找出它为什么是 nil 而不是 Array,然后修复它。很有可能它引用了在你的 development 环境中定义但不在你的 test 环境中定义的某些内容,这就是为什么你在 test 环境中会遇到这个错误。对你的测试的其余更改无关紧要——它在 第一行 失败,即在运行你的规范之前。 - anothermh
我在起始帖子中添加了这行代码。 - James Rich
3个回答

8
问题在于你缺少一个变量,这个变量是你的Devise初始化程序希望找到的,但只是在测试环境中缺少(而不是开发环境)。
你提供的堆栈跟踪和config/initializers/devise.rb中的第258行是需要的全部信息。首先,让我们看一下堆栈跟踪:
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)>'

从下往上看,我们可以看到你的规范中的第一行是导致问题的原因。如果你跟踪堆栈,你会发现它最终在config/initializers/devise.rb:258结束,并且抱怨某个调用[]方法的东西没有得到预期的对象类型,而是得到了nil
查看第258行,你会发现:
config.omniauth :facebook, Rails.application.secrets.facebook[:key],  Rails.application.secrets.facebook[:secret], scope: 'email', info_fields: 'email, name'

所以你可以看到,有两次调用[]
Rails.application.secrets.facebook[:key]
Rails.application.secrets.facebook[:secret]

预期的是调用 Rails.application.secrets.facebook 将返回一个 Enumerable 对象(如数组或哈希表),但实际上它返回了 nil,当尝试运行 nil[:key]nil[:secret] 时会引发异常,因为 NilClass 不是一个 Enumerable 并且没有 [] 方法。您可以在 rails console 中自行测试此问题:
nil[:secret]
=> NoMethodError: undefined method `[]' for nil:NilClass

解决方案是确保调用 Rails.application.secrets.facebook 返回预期的对象类型。简短的答案是编辑 config/secrets.yml,以确保所需的值在 test 环境中存在。
我已经很久没有使用 devise 了,但我认为你可以安全地在 test 环境中使用与 development 环境相同的值。你可以在其他地方阅读有关 secrets() 的更多信息,但 config/secrets.yml 的基本模板如下:
environment:
  key: value

例如:

test:
  my_secret_key: my_secret_value

将缺失的facebook密钥复制并粘贴到test环境中应该是相当简单的。更改后,您可以验证它是否有效:

$ RAILS_ENV=test rails console
Rails.application.secrets.facebook[:key]
=> <your key here>

如果那个可行,就用 rspec 运行你的规范,然后它应该能够成功通过第一行。(假设没有其他漏洞或缺少的机密信息)

我很欣赏第一行告诉我们所有需要知道的信息,特别是缺失的文件不是初始化程序(在我的情况下是一个规范助手)。 - stevec

3

我遇到了非常类似的错误,下面是我的解决方法:

运行rspec --backtrace

这可能会产生大量控制台输出。滚动到顶部,从顶部开始阅读。它会告诉您问题开始的文件和发生错误的行。转到该文件(和该行),找出缺少什么。

在我的情况下,实际上是credentials.yml中缺少了一个变量,但情况因人而异。就像@anothermh给出的精彩答案一样,它基本上是在告诉你缺少了某些东西,所以您必须找出缺少了什么并确保提供它。


2

我遇到了同样的错误,但当我运行bundle exec rake spec而不是bundle exec rspec时,它可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接