【发布时间】:2015-11-12 08:25:37
【问题描述】:
我有一个可确认的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? 返回 @987654329 @。 ENV['STAGING'] 也返回 nil。有没有办法做到这一点,还是我只需要复制粘贴每个示例中的代码?
编辑:因此,问题的第二层似乎是另一个范围界定问题。我正在通过调用User.create 进行测试,它从after_create 挂钩中调用了我的skip_conf! 方法。这失败了,因为我存根的Rails.env 不会影响那个钩子(看起来)。
接下来,我尝试使用User.new 构建一个User 模型,然后直接调用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(并在我的User 模型中编写一个空的skip_conf 方法),测试就会运行。有任何想法吗?如有必要,我可以将其作为集成测试运行,但我觉得在 RSpec 中测试具有副作用的简单方法应该不难。
【问题讨论】:
-
你用的是
user和@user,不应该是user吗? -
哎呀,是的,谢谢。我有点搞砸了。现在修复了,但仍然是同样的问题。在那条线上没有失败。
标签: ruby-on-rails ruby rspec devise devise-confirmable