ruby-on-rails - 使用 RSpec 测试受 Rails 中“config”下定义的常量影响的行为
问题描述
config/environment.rb
我有一个 Rails 应用程序,它在:中定义了以下常量RABBIT_ENABLED = ENV.key? ("RABBIT_PORT")
,它是一个布尔值。同时在另一个文件中config/initializers/rabbit.rb
,我有一些看起来像这样的代码:
if RABBIT_ENABLED
options.merge(load_rabbit_env!)
else
# do something else
end
此load_rabbit_env!
方法尝试使用读取其他环境变量ENV.fetch
,因此容易引发异常。这正是我想要测试的。
我希望能够编写一个测试,在其中我可以根据RABBIT_ENABLED
是真还是假来断言我的 RabbitMQ 启动的行为(例如,如果常量为真但缺少其他环境变量,则会引发异常)。但是,该常量似乎无法存根,可能是因为常量是由 RSpec 运行时定义的,它已经加载了 Rails 应用程序并且不会重新读取它的值以进行测试?
我想知道在这种情况下人们会建议我做什么。理想情况下,我不想更改常量的定义位置,但我知道这里可能有必要。
解决方案
所以你可以通过存根RABBIT_ENABLED
true 或 false创建 2 个上下文
describe "your test" do
context "RABBIT ENABLED"
before(:each) do
stub_const("RABBIT_ENABLED", true)
end
# ...
end
context "RABBIT DISABLE" do
before(:each) do
stub_const("RABBIT_ENABLED", false)
end
# ...
end
end
更新
如果您想测试initializer
,您可以隔离配置的逻辑,然后您可以将该逻辑作为普通的 ruby 对象进行测试,您可以在其中存根常量:
# config/testable/rabbit_config.rb
class RabbitConfig
def apply(config, *args)
# testable logic
if RABBIT_ENABLED
options.merge(load_rabbit_env!)
else
# do something else
end
end
end
创建一个第一个初始化程序0_load_testable_config_object.rb
,它将在加载testable configs
其他初始化程序之前加载所有初始化程序(或者您可以手动要求)
# config/initializers/0_load_testable_config_object.rb
Dir[File.join(Rails.root, "config", "testable", "**/*.rb")].each {|l| require l }
# config/initializers/rabbit.rb
Rabbit.setup do |config|
RabbitConfig.new.apply(config)
# ...
end
现在你可以像上面一样RabbitConfig
通过 stub_const进行测试。RABBIT_ENABLED
推荐阅读
- python - 请求 Json 在 python 3.9 中抛出错误
- java - SeekBar RGB 选择器不断停止
- python - 如何基于在某些行中可能以相反顺序排列的两个不同列合并两个数据框?
- java - 码头错误“IllegalStateException:无方法:
... 在课堂上 ...Configuration$ClassList" - ios - 如何使用 Xamarin 表单获取 iOS 的设备序列号
- javascript - Javascript 中类似 Java 常量的 Map 对象
- python - Pandas - 如何将非数字值更新为数字并求和?熊猫
- angularjs - 有没有办法为金字塔高图添加边界半径
- c++ - Gcc 自定义运算符 new[] 和 delete[] 对于对齐的类有错误 - 地址清理程序报告缓冲区溢出
- python - 内存错误python 3