使用 shared_context

使用 shared_context 定义一个将在示例组上下文中执行的块,无论是本地使用示例组中的 include_context,还是全局使用 config.include_context

当通过匹配元数据隐式包含共享上下文时,正常方法是在示例组上定义匹配元数据,在这种情况下,上下文包含在整个组中。但是,您也可以选择在单个示例中包含它。RSpec 将每个示例视为具有包含一个示例的单例示例组(类似于 Ruby 的单例类)。

背景

假设 一个名为“shared_stuff.rb”的文件,其中包含

RSpec.configure do |rspec|
  # This config option will be enabled by default on RSpec 4,
  # but for reasons of backwards compatibility, you have to
  # set it on RSpec 3.
  #
  # It causes the host group and examples to inherit metadata
  # from the shared context.
  rspec.shared_context_metadata_behavior = :apply_to_host_groups
end

RSpec.shared_context "shared stuff", :shared_context => :metadata do
  before { @some_var = :some_value }
  def shared_method
    "it works"
  end
  let(:shared_let) { {'arbitrary' => 'object'} }
  subject do
    'this is the subject'
  end
end

RSpec.configure do |rspec|
  rspec.include_context "shared stuff", :include_shared => true
end

声明一个共享上下文并使用 include_context 包含它

假设 一个名为“shared_context_example.rb”的文件,其中包含

require "./shared_stuff.rb"

RSpec.describe "group that includes a shared context using 'include_context'" do
  include_context "shared stuff"

  it "has access to methods defined in shared context" do
    expect(shared_method).to eq("it works")
  end

  it "has access to methods defined with let in shared context" do
    expect(shared_let['arbitrary']).to eq('object')
  end

  it "runs the before hooks defined in the shared context" do
    expect(@some_var).to be(:some_value)
  end

  it "accesses the subject defined in the shared context" do
    expect(subject).to eq('this is the subject')
  end

  group = self

  it "inherits metadata from the included context" do |ex|
    expect(group.metadata).to include(:shared_context => :metadata)
    expect(ex.metadata).to include(:shared_context => :metadata)
  end
end

我运行 rspec shared_context_example.rb

那么 这些示例应该全部通过。

声明一个共享上下文,使用 include_context 包含它,并使用另一个块扩展它

假设 一个名为“shared_context_example.rb”的文件,其中包含

require "./shared_stuff.rb"

RSpec.describe "including shared context using 'include_context' and a block" do
  include_context "shared stuff" do
    let(:shared_let) { {'in_a' => 'block'} }
  end

  it "evaluates the block in the shared context" do
    expect(shared_let['in_a']).to eq('block')
  end
end

我运行 rspec shared_context_example.rb

那么 这些示例应该全部通过。

声明一个共享上下文,并使用元数据包含它

假设 一个名为“shared_context_example.rb”的文件,其中包含

require "./shared_stuff.rb"

RSpec.describe "group that includes a shared context using metadata", :include_shared => true do
  it "has access to methods defined in shared context" do
    expect(shared_method).to eq("it works")
  end

  it "has access to methods defined with let in shared context" do
    expect(shared_let['arbitrary']).to eq('object')
  end

  it "runs the before hooks defined in the shared context" do
    expect(@some_var).to be(:some_value)
  end

  it "accesses the subject defined in the shared context" do
    expect(subject).to eq('this is the subject')
  end

  group = self

  it "inherits metadata from the included context" do |ex|
    expect(group.metadata).to include(:shared_context => :metadata)
    expect(ex.metadata).to include(:shared_context => :metadata)
  end
end

我运行 rspec shared_context_example.rb

那么 这些示例应该全部通过。

声明一个共享上下文,并使用单个示例的元数据包含它

假设 一个名为“shared_context_example.rb”的文件,其中包含

require "./shared_stuff.rb"

RSpec.describe "group that does not include the shared context" do
  it "does not have access to shared methods normally" do
    expect(self).not_to respond_to(:shared_method)
  end

  it "has access to shared methods from examples with matching metadata", :include_shared => true do
    expect(shared_method).to eq("it works")
  end

  it "inherits metadata from the included context due to the matching metadata", :include_shared => true do |ex|
    expect(ex.metadata).to include(:shared_context => :metadata)
  end
end

我运行 rspec shared_context_example.rb

那么 这些示例应该全部通过。