我有一个模型,其中一些验证是根据它们正在运行的环境(通过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