我有一个可验证的devise
模型,我试图为其编写规范,并且如果我们进入,它会获得一些跳过确认的代码分期或开发环境。为了测试它,我试图存根Rails.env.*?
环境方法,所以我将方法定义为帮助处理所有情况:
def enable_environment(env)
if env == :staging
stub_env('STAGING', 'true')
end
# clear all environments
allow(Rails.env).to receive(:test?) { false }
allow(Rails.env).to receive(:development?) { false }
allow(Rails.env).to receive(:production?) { false }
# turn on environment of choice
if env == :production || env == :staging
allow(Rails.env).to receive(:production?) { true }
elsif env == :development
allow(Rails.env).to receive(:development?) { true }
elsif env == :test
allow(Rails.env).to receive(:test?) { true }
else
raise 'no such environment'
end
end
但是,看起来这些存根只是作用于方法的范围 - 如果我在示例中调用enable_environment(:staging)
并在byebug
之后调试,Rails.env.test?
返回true
和Rails.env.production?
返回false
。 ENV['STAGING']
也会返回nil
。有没有办法做到这一点,或者我只需要复制粘贴每个例子中的代码?
编辑:所以,问题的第二层似乎是另一个范围问题。我正在通过调用User.create
进行测试,该skip_conf!
调用我after_create
方法的Rails.env
方法。这失败了,因为我发布的User
不会影响该挂钩(似乎)。
接下来,我尝试使用User.new
构建skip_conf!
模型,然后直接在其上调用skip_conf!
。这会失败,因为NoMethodError: undefined method '+' for nil:NilClass
有副作用(我得到skip_conf
)。我尝试过其他方法(例如User
,没有副作用),并且它们有效。我的class User < ActiveRecord::Base
after_create :skip_conf!
# ...
def skip_conf!
self.confirm unless (Rails.env.production? && !ENV['STAGING'] == 'true') || Rails.env.test?
end
end
模型如下所示:
context 'in testing' do
before :each do
@user = User.new(
# params
)
end
it 'shouldn\'t skip confirmation' do
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development'))
@user.skip_conf!
expect(@user.confirmed?).to be_falsey
end
end
新的测试代码:
user.skip_conf!
如果我将user.skip_conf
更改为skip_conf
(并在我的User
模型中编写一个空的SELECT *
FROM INFORMATION_SCHEMA.VIEW_COLUMN_USAGE AS cu
JOIN INFORMATION_SCHEMA.COLUMNS AS c
ON c.TABLE_SCHEMA = cu.TABLE_SCHEMA
AND c.TABLE_CATALOG = cu.TABLE_CATALOG
AND c.TABLE_NAME = cu.TABLE_NAME
AND c.COLUMN_NAME = cu.COLUMN_NAME
WHERE cu.VIEW_NAME = '<your view name>'
AND cu.VIEW_SCHEMA = '<your view schema>'
方法),则运行测试。有任何想法吗?如果有必要,我可以将其作为集成测试运行,但我觉得在RSpec中测试一个带有副作用的简单方法并不困难。
答案 0 :(得分:0)
如果在env
上隐藏Rails
,而在test?
上隐藏env
等。
before do
rails_env = "test".inquirer
allow(Rails).to receive(:env).and_return(rails_env)
end