在RSpec帮助器方法

时间:2015-08-19 07:08:00

标签: ruby-on-rails ruby rspec devise devise-confirmable

我有一个可验证的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?返回trueRails.env.production?返回falseENV['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中测试一个带有副作用的简单方法并不困难。

1 个答案:

答案 0 :(得分:0)

如果在env上隐藏Rails,而在test?上隐藏env等。

before do 
  rails_env = "test".inquirer
  allow(Rails).to receive(:env).and_return(rails_env)
end