I have defined a constant in config/environment.rb called LOCAL_SETTINGS that I use for configuration and use throughout my app. It's a YAML file stored in config/local_settings.yml and will sometimes contain sensitive data like API keys etc.
I'm currently trying to write a spec for a method that uses LOCAL_SETTINGS["slack"]["slack_token"].
The problem is that the constant is not being stubbed for my expectations. ie expect(subject.path).to eq(help_request) fails because it returns a path including the non-stubbed LOCAL_SETTINGS hash.
However if I put a debugger in beneath stub_const and then type LOCAL_SETTINGS, I can see that stub_const has worked.
My questions are:
config/environment.rb?My config/environment.rb file:
# Load the Rails application.
require_relative 'application'
LOCAL_SETTINGS = YAML.load_file("#{Rails.root}/config/local_settings.yml")
# Initialize the Rails application.
Rails.application.initialize!
My spec:
describe RequestBuilder, type: :model do
let(:help_params) { {"user_name"=>"some_user_name", "text"=>"release-bot help"} }
let(:help_builder) { RequestBuilder.new(help_params) }
let(:help_request) { "/api/files.upload?file=lib%2Fresponses%2Fhelp&filetype=ruby&channels=stubbed_channel&token=stubbed_token" }
let(:slack_settings) { {"slack"=>{"slack_token"=>"stubbed_token", "slack_channel"=>"stubbed_channel"}} }
context 'Given an incoming request' do
context 'With a correctly formatted request' do
context 'And the "help" command' do
subject { help_builder.build_request_hash }
it 'builds a request containing the help data' do
stub_const("LOCAL_SETTINGS", slack_settings)
expect(subject).to have_key(:request)
expect(subject[:request].path).to eq(help_request)
end
end
end
end
end
If you're using Rails, and you already have a .yaml file in the config directory, I would suggest looking at Rails custom configuration to load the YAML file. This way you'll be able to isolate any credentials from your test environment without having to stub the LOCAL_SETTINGS const for every test or change any of your classes.
# config/local_settings.yml
development:
slack_token: some_dev_token
slack_channel: some_channel
test:
slack_token: fake_token
slack_channel: fake_channel
production:
slack_token: <%= ENV['SLACK_TOKEN'] %>
slack_channel: <%= ENV['SLACK_CHANNEL'] %>
And then to load this configuration file:
# config/application.rb
module MyApp
class Application < Rails::Application
config.local_settings = config_for(:local_settings)
end
end
Then you can access the values from Rails.configuration.local_settings['slack_token'] rather than from the LOCAL_SETTINGS constant.
Another blog post highlighting the custom configuration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With