尝试更改 RSpec 模型规范中的环境变量

Trying to change environment variable within RSpec model spec

我有一个用户模型,它根据环境变量 ENV['APP_FOR'] 进行了不同的验证。这可以是 "app-1" 或 "app-2"。 app-1 验证用户名,而 app-2 验证电子邮件地址。这是我的 app-1 用户模型规范:

require 'rails_helper'

RSpec.describe User, type: :model do

  include Shared::Categories

  before do
    ENV['APP_FOR']='app-1'
  end

  context "given a valid User" do
    before { allow_any_instance_of(User).to receive(:older_than_18?).and_return(true) }

    it {should validate_presence_of :username}
  end
end 

这是 app-2 的用户模型规范

require 'rails_helper'

RSpec.describe User, type: :model do

  include Shared::Categories

  before do
    ENV['APP_FOR']='app-2'
  end

  context "given a valid User" do
    before { allow_any_instance_of(User).to receive(:older_than_18?).and_return(true) }

    it {should validate_presence_of :email}
  end
end

我的问题是环境变量没有像我期望的那样设置在 before 块中。关于如何做到这一点有什么想法吗?

编辑 1

这是我的验证实现。我使用了一个扩展用户模型的问题:

module TopDogCore::Concerns::UserValidations
  extend ActiveSupport::Concern
  included do

    if ENV['APP_FOR'] == 'app-1'
      validates :username,
                presence: true,
                uniqueness: true        

    elsif ENV['APP_FOR'] == 'app-2'
      validates :email, 
                presence: true,
                uniqueness: true
    end
  end
end

试一试

module TopDogCore::Concerns::UserValidations
  extend ActiveSupport::Concern
  included do

    validates :username,
      presence: true,
      uniqueness: true, if: -> { ENV['APP_FOR'] == 'app-1' }

    validates :email,
      presence: true,
      uniqueness: true, if: -> { ENV['APP_FOR'] == 'app-2' }
  end
end

像这样存根你的常量

before do
  stub_const("APP_FOR", 'app-2')
end

查看 Stubbing Constants 文档

RSpec 在示例中的 运行 代码之前加载主题 class。当你这样做时:

before do
  ENV['APP_FOR'] = # ...
end

太晚了。 class 定义已经执行。您可以通过简单地从 class 定义中打印 ENV['APP_FOR'] 的值来亲自看到这一点(在您的情况下,包含的问题)。它是 nil,因为在加载 class 源文件时没有设置环境变量。

使用 lambda () 延迟计算应该有效。您可以尝试使用自己的测试而不是 shoulda_matchers 提供的测试,例如:

expect(subject.valid?).to be false
expect(subject.errors[:username].blank?).to be false