"include_examples"和"it_behaves_like"之间有什么区别?

GMA*_*GMA 41 ruby rspec

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

文件说:

include_examples - 包括当前背景下的示例

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

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

另外,是it_should_behave_likeit_behaves_like刚才的同义词?

jay*_*eff 41

你可能知道如何使用describe,context,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
Run Code Online (Sandbox Code Playgroud)

如果您运行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
Run Code Online (Sandbox Code Playgroud)

所以区别在于如何读取规范,例如在失败的情况下.

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


还有,it_should_behave_like和it_behaves_like只是同义词吗?

几乎,上下文的名称不同.it should behave like ...VS behaves like ....再一个美学问题.

  • 所以要澄清一下:我使用的三个对测试是否通过/失败没有影响,它只是一个美学/可读性的选择? (4认同)
  • @GeorgeMillo 正是:) (2认同)

ron*_*ona 19

还有就是在你将参数传递给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
Run Code Online (Sandbox Code Playgroud)

你实际上是这样做的(注意第一个例子会失败):

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
Run Code Online (Sandbox Code Playgroud)

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

  • 另请注意,如果在给定 `include_examples` 方法的块中添加一些 let 变量,也会观察到相同的效果:在 `include_examples('My Shared Examples) { let(:variable_only_for_shared_example) { some }` 中的 `let(:variable_only_for_shared_example)如果您之前已经定义过)` 将被覆盖。如果您的 rspec 共享示例旨在重用 let 变量,并且您“认为”在块中定义它们就可以了,那么这可能会成为一个陷阱。 (2认同)