在RSPEC套件中的所有示例中设置变量一次(不使用全局变量)



rspec套件中所有示例都使用一次变量一次的常规方法是什么?

我当前在spec_helper中设置了一个全局变量,该变量检查规格是否在"调试模式"

中运行
$debug = ENV.key?('DEBUG') && (ENV['DEBUG'].casecmp('false') != 0) && (ENV['DEBUG'].casecmp('no') != 0)

如何在套件中的所有示例中使用此信息,而无需使用全局变量,而不重新计算每个上下文和/或示例的值?(我的理解是,使用before(:all)块将每个上下文重新计算一次;但是,before(:suite)不能用于设置实例变量。)

(注意:我要更多地了解解决这个特定问题的好设计。我知道一个全球并不重要。)

为此,我通常编写可以在spec_helper.rb文件中包含的自定义模块。

假设我正在测试后端API,并且我不想每次JSON响应主体进行解析。

spec/
spec/spec_helper.rb
spec/support/request_helper.rb
spec/controllers/api/v1/users_controller_spec.rb

i首先在支持子文件夹下方的模块中定义一个函数。

# request_helper.rb
module Request
  module JsonHelpers
    def json_response
      @json_response ||= JSON.parse(response.body, symbolize_names: true)
    end
  end
end

然后,我默认将此模块用于某些测试类型

#spec_helper.rb
#...
RSpec.configure do |config|
  config.include Request::JsonHelpers, type: :controller
end

然后我使用测试中定义的方法。

# 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

在您的情况下,您可以创建一个模块,例如

module EnvHelper
  def is_debug_mode?
    @debug_mode ||= ENV['DEBUG']
  end
end

然后您可以包括它,只需在测试中使用方法is_debug_mode?

有一种简单的方法可以将所有设置内容保留在spec_helper.rb中,包括自定义变量,并在测试中访问这些变量。以下是从RSPEC核心3.10文档中修改的,并且不是轨道特定的。

RSpec.configure创建一个名为my_variable的新设置,并给它一个值,例如:

# spec/spec_helper.rb
RSpec.configure do |config|
  config.add_setting :my_variable
  config.my_variable = "Value of my_variable"
end

从您的测试中访问RSpec.configuration中的新读取属性:

# spec/my_spec.rb
RSpec.describe(MyModule) do
  it "creates an instance of something" do
    my_instance = MyModule::MyClass.new(RSpec.configuration.my_variable)
  end
end

最新更新