52

it_behaves_like在 RSpec 中,和有什么区别include_examples

文档说:

include_examples— 包括当前上下文中的示例

it_behaves_like "name"— 在嵌套上下文中包含示例

但这实际上意味着什么?用另一个替换一个似乎对我的测试是通过还是失败没有影响。在某些情况下,是否有理由偏爱其中一种?

另外,是it_should_behave_likeit_behaves_like只是同义词吗?

4

2 回答 2

56

您可能知道如何使用describecontext和清楚itspecify传达代码的一个方面。提供的嵌套上下文it_behaves_like可用于改善与读者的这种沟通。

我的示例将基于 RSpec 文档中给出的共享示例示例

shared_examples "a collection" do
  context "initialized with 3 items" do
    it "says it has three items" do
      # ...
    end
  end
end

describe Array do
  it_behaves_like "a collection"
  include_examples "a collection"
end

如果你运行 RSpec,--format documentation你会得到以下输出:

Array
  behaves like a collection
    initialized with 3 items
      says it has three items
  initialized with 3 items
    says it has three items

因此,不同之处在于如何读取规范,例如在失败的情况下。

您喜欢哪种风格是您喜欢阅读规格的美学问题。此外,如果您在团队中工作以提高一致性,您会建议始终使用相同的风格。


另外,it_should_behave_like 和 it_behaves_like 是同义词吗?

几乎,上下文的名称不同。it should behave like ...behaves like ...。又是美学问题。

于 2013-10-24T04:52:37.020 回答
27

将参数传递给 shared_examples 的情况有所不同

在他们的文档中的警告中很好地解释了这一点:

警告:当您在当前上下文中多次包含参数化示例时,您可能会覆盖以前的方法定义并最终声明获胜。因此,如果您有这种共享示例(或共享上下文)

RSpec.shared_examples "some example" do |parameter|
  \# Same behavior is triggered also with either `def something; 'some value'; end`
  \# or `define_method(:something) { 'some value' }`
  let(:something) { parameter }
  it "uses the given parameter" do
    expect(something).to eq(parameter)
  end
end

RSpec.describe SomeClass do
  include_examples "some example", "parameter1"
  include_examples "some example", "parameter2"
end

您实际上正在这样做(请注意,第一个示例将失败):

RSpec.describe SomeClass do
  \# Reordered code for better understanding of what is happening
  let(:something) { "parameter1" }
  let(:something) { "parameter2" }

  it "uses the given parameter" do
    \# This example will fail because last let "wins"
    expect(something).to eq("parameter1")
  end

  it "uses the given parameter" do
    expect(something).to eq("parameter2")
  end
end

为了防止这种微妙的错误,如果您在同一上下文中声明多个具有相同名称的方法,则会发出警告。如果您收到此警告,最简单的解决方案是将 include_examples 替换为 it_behaves_like,这样可以避免方法覆盖,因为 it_behaves_like 创建了嵌套上下文

于 2016-07-25T20:40:50.517 回答