How do I test different configurations which are set at Rails boot time?
I'm currently working on a fix related to an issue in spree commerce: https://github.com/spree/spree/issues/12231
To test the failing behavior before I apply my fix, I wrote a Rspec test like this:
describe 'new product creation' do
context 'when runtime config always_use_translations is true' do
let(:product) { build(:product, stores: [store]) }
before do
Spree::RuntimeConfig.always_use_translations = true
end
it 'doesnt raise NotNullViolation error' do
expect { product.save }.not_to raise_error
end
end
end
But this can't work because when the test app boots up Spree::RuntimeConfig.always_use_translations
is unset and the Model gets loaded with that accordingly: https://github.com/spree/spree/blob/25be0ee89d86da81b2b624405475cf48b5195a85/core/app/models/spree/product.rb#L47
Changing Spree::RuntimeConfig.always_use_translations = true
never reaches through the already loaded Model. Unless I can reload it somehow?
Since in Rails.env.test
the config.enable_reloading = false
I had no luck trying something eg. Rails.application.reloader.reload!
to get the Model reloaded after I set the configuration in the before block.
The only way to get my test to do what it should was this:
describe 'new product creation' do
context 'when runtime config always_use_translations is true' do
before do
Spree::RuntimeConfig.always_use_translations = true
if defined?(Spree::Product)
Spree.send(:remove_const, :Product)
load File.join(Spree::Core::Engine.root, 'app/models/spree/product/webhooks.rb')
load File.join(Spree::Core::Engine.root, 'app/models/spree/product.rb')
end
end
it 'doesnt raise NotNullViolation error' do
product = Spree::Product.new name: 'Test always_use_translations'
expect { product.save }.not_to raise_error
end
end
end
But this feels not right and most important breaking other test which run after it.
Did anyone have an idea how to test something like this?
Great question! For configs set at boot time, one approach is to use environment variables and restart the Rails app between tests with different values. For automated testing, consider wrapping config-dependent logic in a class or method that reads from Rails.configuration or ENV, so you can stub or mock it in tests. You can also use with_env or similar helpers in RSpec to temporarily override ENV values. Let me know more about your setup—happy to help further!