在rspec中将存根与断言分开

时间:2012-03-12 23:28:59

标签: ruby rspec bdd rspec2

我正在使用rspec和rspec模拟库来进行存根/模拟,但我开始认为存在一个方法并断言它如何被使用之间的界限是模糊的。在我的测试中,我经常写一些类似的东西:

before(:each) do
  subject.should_receive(:sum).once.with([1, 2, 3]).and_return(6)
end

it("should do something that relies on sum") do
  subject.call_something([1, 2, 3]).should == 24
end

但我的断言是什么?那call_something([1, 2, 3])

  • 返回24
  • 在执行期间调用sum([1, 2, 3])

但是,只有一个it块 - 另一个断言隐藏在存根定义中。换句话说,我的存根也是我的断言。将两者分开是不是更清楚,并明确断言如何调用存根方法:

before(:each) do
  # set up what my stub should return for a given input
  subject.may_receive(:sum).with([1, 2, 3]).and_return(6)
end

# assert how my stub was actually called
it("should have called sum with 1, 2, 3") do
  # this is pseudo-rspec
  subject.call_something([1, 2, 3]).should have_called(:sum).on(subject).once.with([1, 2, 3])
end
it("should do something that relies on sum") do
  subject.call_something([1, 2, 3]).should == 24
end

这种方式非常清楚我所断言的是因为我的存根定义和断言已经分开了。我可以在顶部设置我的测试,然后在底部检查它的行为,而不混合两者。

所以,我的问题是,有没有办法做到这一点?大多数模拟框架的工作方式与rspec-mocks相同,并定义了stub方法如何与预期行为一起使用的契约,然后在结束时自动检查断言。

我的观点是关于BDD如何工作的概念,可能有点微妙。让我知道我需要进一步澄清它!

1 个答案:

答案 0 :(得分:2)

你是对的。 should_receive 断言(更确切地说,它是期望),不应该进入before块。如果您需要should_receive的存根副作用,请在before中单独存根:

before do
  subject.stub(:sum).and_return(6)
end

it "should do something that relies on sum" do
  subject.should_receive(:sum).once.with([1, 2, 3]).and_return(6)
  subject.call_something([1, 2, 3]).should == 24
end

这可以使存根和期望分开,也可以分开。