Set variable once for all examples in RSpec suite (without using a global variable)

烈酒焚心 提交于 2019-12-22 18:42:50

问题


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.)


回答1:


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.



来源:https://stackoverflow.com/questions/46200096/set-variable-once-for-all-examples-in-rspec-suite-without-using-a-global-variab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!