有没有办法使用 RSpec 在模型中测试环境定义的动态验证



我有一个模型,其中一些验证是根据它们正在运行的环境(通过ENV变量)动态定义的。

例如,我在开发和测试中使用设置为'testnet3'网络的 ENV['NETWORK'] 变量,在生产中使用设置为'bitcoin'网络的变量。然后,假设我有一个名为 Transaction 的模型,其验证集动态如下:

Transaction < ActiveRecord::Base
  validates :output_address,
    presence: output_address_presence_requirement_for ENV['NETWORK'] 
end
# somewhere exists the 'output_address_presence_requirement_for' function
def output_address_presence_requirement_for(network)
  if network == 'testnet3'
    false
  else
    true
  end
end

然后,我有两组规范:一套用于使用"比特币"网络(生产)时的模型行为,另一套用于使用"testnet3"网络(开发/测试)时的行为。当它们单独运行每个文件时,它们按预期工作,但是当一个接一个地运行时,例如在rspec spec/models上,更改 ENV 变量的值似乎没有效果,并且第二组规范失败。

我尝试使用 climate_control ,对 ENV 的调用存根,甚至直接设置 ENV 变量的值,每种情况下的结果都相同:如果单独运行,测试通过,第二组测试失败,如果将它们作为一个整体运行。

似乎 RSpec 在运行一组测试时重用相同的 Rails 环境,并且在调用第一组测试时定义了模型验证,但在调用第二组测试时不会重新定义。

我可以使用具有不同验证的不同模型来存储信息,具体取决于所使用的网络,但我想避免使用它,因为它需要在控制器上使用更复杂的逻辑和更多规范。

是否可以在 RSpec 端执行一些操作,使其在运行规范文件之前刷新环境?

简单来说:

我想,一旦你完全运行测试,文件是必需的,验证器被定义一次

因此,即使您在测试中更改了 ENV['NETWORK'] 的值,presence键的值也保持不变。

使用每次验证对象时读取环境变量的验证方法。

下面是您共享的示例代码的示例:

validate :validator_name
def validator_name
  if (ENV['NETWORK'] != 'testnet3') && output_address.blank?
    # add errors here
  end
end

最新更新