在RSpec中自动共享上下文

时间:2012-07-01 14:11:45

标签: ruby rspec

我想在我的规格之间分享一个记忆方法。所以我尝试使用像这样的共享上下文

RSpec.configure do |spec|
  spec.shared_context :specs do
    let(:response) { request.execute! }
  end
end

describe 'something' do
  include_context :specs
end

一切正常。但我有大约60个spec文件,所以我不得不明确地在每个文件中包含上下文。有没有办法为let中的所有示例组自动包含共享上下文(或至少spec_helper.rb定义)?

像这样的东西

RSpec.configure do |spec|
  spec.include_context :specs
end

5 个答案:

答案 0 :(得分:29)

您可以使用before通过configure-class-methodsConfiguration设置全局RSpec.configure摘要:

RSpec.configure {|c| c.before(:all) { do_stuff }}
let不支持

RSpec.configure,但可以通过将其包含在SharedContext module中来设置全局let模块使用config.before

module MyLetDeclarations
  extend RSpec::Core::SharedContext
  let(:foo) { Foo.new }
end
RSpec.configure { |c| c.include MyLetDeclarations }

答案 1 :(得分:5)

你可以这样做几乎:有一种包含模块的机制,模块包含有自己的回调机制。

假设我们有一个disconnected共享上下文,我们希望在没有数据库连接的情况下运行我们的所有模型规范。

shared_context "disconnected"  do
  before :all do
    ActiveRecord::Base.establish_connection(adapter: :nulldb)
  end

  after :all do
    ActiveRecord::Base.establish_connection(:test)
  end
end

您现在可以创建一个包含该上下文的模块。

module Disconnected
  def self.included(scope)
    scope.include_context "disconnected"
  end
end

最后,你可以按照正常的方式将该模块包含在所有规格中(我已经证明只为模型做这件事,只是为了表明你可以),这几乎就是你所要求的。

RSpec.configure do |config|
  config.include Disconnected, type: :model
end

适用于rspec-core 2.13.0和rspec-rails 2.13.0。

答案 2 :(得分:5)

在RSpec 3+中,这可以通过以下方式实现 - 基于Jeremy Peterson的回答。

# spec/supprt/users.rb
module SpecUsers
  extend RSpec::SharedContext

  let(:admin_user) do
    create(:user, email: 'admin@example.org')
  end
end

RSpec.configure do |config|
  config.include SpecUsers
end

答案 3 :(得分:1)

另一种方法是automatically share examples via metadata。所以:

shared_context 'a shared context', a: :b do
  let(:foo) { 'bar' }
end

describe 'an example group', a: :b do
  # I have access to 'foo' variable
end

我使用它的最常见方式是在rspec-rails中,一些共享上下文取决于示例组类型。因此,如果您有config.infer_spec_type_from_file_location!,则可以执行以下操作:

shared_context 'a shared context', type: :controller do
  let(:foo) { 'bar' }
end

describe SomeController do
  # I have access to 'foo' variable
end

答案 4 :(得分:0)

此外,如果你需要能够在规范内的before块中使用共享数据,就像我一样,尝试包含它(如果它的Rails项目):

module SettingsHelper
  extend ActiveSupport::Concern

  included do
    attr_reader :default_headers

    before :all do
      @default_headers = Hash[
          'HTTP_HOST' => 'test.lvh.me'
        ]
    end

    after :all do
      @default_headers = nil
    end
  end
end

RSpec.configure do |config|
  config.include SettingsHelper
end

或尝试类似的东西,看看@threedaymonk的答案。