What is the conventional way to set a variable once to be used by all examples in an RSpec suite?
I currently set a global variable in spec_helper
that checks whether the specs are being run in a "debug mode"
$debug = ENV.key?('DEBUG') && (ENV['DEBUG'].casecmp('false') != 0) && (ENV['DEBUG'].casecmp('no') != 0)
How do I make this information available to all the examples in the suite without using a global variable and without re-computing the value for each context and/or example? (My understanding is that using a before(:all)
block would re-compute it once per context; but, that before(:suite)
can't be used to set instance variables.)
(Note: I'm asking more to learn about good design that to address this specific problem. I know one global isn't a big deal.)
for this purpose I usually write custom modules that I can include in the spec_helper.rb
file.
Let's say that I am testing a back-end API and I don't want to parse every time the JSON response body.
spec/
spec/spec_helper.rb
spec/support/request_helper.rb
spec/controllers/api/v1/users_controller_spec.rb
I first define a function in a module placed under the support subfolder.
# request_helper.rb
module Request
module JsonHelpers
def json_response
@json_response ||= JSON.parse(response.body, symbolize_names: true)
end
end
end
Then I include this module by default for some test types
#spec_helper.rb
#...
RSpec.configure do |config|
config.include Request::JsonHelpers, type: :controller
end
Then I use methods defined in the test.
# users_controller_spec.rb
require 'rails_helper'
RSpec.describe Api::V1::UsersController, type: :controller do
# ...
describe "POST #create" do
context "when is successfully created" do
before(:each) do
@user_attributes = FactoryGirl.attributes_for :user
post :create, params: { user: @user_attributes }
end
it "renders the json representation for the user record just created" do
user_response = json_response[:user]
expect(user_response[:email]).to eq(@user_attributes[:email])
end
it { should respond_with 201 }
end
end
In your case, you could create a module such as
module EnvHelper
def is_debug_mode?
@debug_mode ||= ENV['DEBUG']
end
end
Then you can include it and simply use the method is_debug_mode?
in your tests.