我有一个简单的新 Rails 4 应用程序,当我运行 rake test:units
时会破坏开发数据库,即使我已经在 test_helper.rb 中设置了RAILS_ENV。我没想到会这样。以下是重现它的简单步骤。
我有Ruby 2.0.0p247和Rails 4.0.1。
rails new foo
rails generate scaffold gadget
rake db:migrate
我编辑测试/模型/gadget_test.rb 看起来像这样:
require 'test_helper'
class GadgetTest < ActiveSupport::TestCase
test "the env" do
assert_equal "test", Rails.env
end
end
我已经编辑了测试的第一行/test_helper.rb
ENV["RAILS_ENV"] ||= "test"
要成为
ENV["RAILS_ENV"] = "test"
即便如此,当测试调用rake test:units
时,它也会失败:
1) Failure:
GadgetTest#test_the_env test/models/gadget_test.rb:5]:
Expected: "test"
Actual: "development"
对于我设置的较旧的(Rails 3)应用程序,我可以指望它默认为测试环境。我错过了什么?
解开了,用帽子的大尖端来j_mcnally!
为了强制 Rails env 在 Rails 4 中"测试"(可能更早),将 test_helper.rb 的第一行更改为
ENV["RAILS_ENV"] = "test"
这无法重置 Rails.env 的缓存值,但如果您调用
Rails.env = "test"
它将正确重置缓存的值。也就是说,在其他地方已经调用了Rails.env,否则不会设置缓存。一个明显的是 application.rb 中的捆绑器设置,它Bundler.require(:default, Rails.env)
并将其更改为 Bundler.require(:default, ENV['RAILS_ENV'])
(以避免设置缓存)仍然表明初始化中的其他地方也必须调用 Rails.env。所有这些的重要性在于,一些设置会认为它在开发中运行,然后测试将在"测试"环境中运行。
最终答案:我有办法得到我想要的东西,但可能仍然有一些危险点潜伏在那里。
TL;DR 确保require 'rails/test_unit/railtie'
行不会在config/application.rb
中注释掉
我遇到了同样的问题,正在尝试使用Minitest作为TestUnit的替代品,并在没有它的情况下生成Rails应用程序(rails new foobar --skip-test-unit
),但是Minitest仍然使用rails的测试任务。
我在config/applicaiton.rb
中有以下代码:
# require 'rails/test_unit/railtie'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
正如j_mcnally和Fitter Man指出的那样,问题在于Rails.env
在设置ENV['RAILS_ENV']
之前缓存了其值,在我的情况下,它是在Rails.groups
内部调用的。
试图在 Rails 源代码中找到它在调用 rake 任务时如何设置正确的 test
环境,我发现它在被注释掉的rails/test_unit/railtie.rb
中这样做。
因此,解决方案就像取消注释require 'rails/test_unit/railtie'
行一样简单。
希望有帮助。
真正的答案是:我的个人资料引用的 shell 脚本中有一个杂散export RAILS_ENV="development"
。所以这是一个座位到键盘接口故障,直接从 2013 年 10 月 31 日在此线程中:https://github.com/rails/rails/issues/7175
您需要做的就是将其取出,问题就会消失。
据我所知,没有任何理由强迫Rails.env
进行测试。因此,如果您的测试在错误的环境中运行,则在代码中的某个位置设置了环境。
对我来说,这是由环境导出引起的,我没有意识到有人已经放在了该应用程序.rvmc
文件的第一行。
从该文件中删除该export RAILS_ENV=development
行并重新启动终端解决了该问题。