“include_examples”和“it_behaves_like”之间有什么区别?

时间:2013-10-24 03:18:56

标签: ruby rspec

在RSpec中,it_behaves_likeinclude_examples之间有什么区别?

documentation说:

  

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

     

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

但这究竟意味着什么?将一个替换为另一个似乎对我的测试是通过还是失败没有影响。在某些情况下,有理由更喜欢一个吗?

此外,it_should_behave_likeit_behaves_like只是同义词吗?

2 个答案:

答案 0 :(得分:38)

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

我的示例基于shared examples的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

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

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 ... vs behaves like ...。再一个美学问题。

答案 1 :(得分:17)

如果您将参数传递给shared_examples, 会有区别。

在警告in their doc中解释得非常好:

  

警告:在当前上下文中包含参数化示例时   次,您可以覆盖以前的方法定义和最后的声明获胜。   所以如果你有这种共享的例子(或共享的上下文)

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 with it_behaves_like,以这种方式覆盖   因为it_behaves_like

创建的嵌套上下文而被避免