【问题标题】:Separating stubs from assertions in rspec将存根与 rspec 中的断言分开
【发布时间】:2012-03-29 09:29:04
【问题描述】:

我正在使用 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 相同,并定义如何使用存根方法以及预期行为的协定,然后在最后自动检查断言。

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

【问题讨论】:

    标签: ruby rspec bdd rspec2


    【解决方案1】:

    你是对的。 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
    

    这使存根和期望分开,并且它们所属的位置。

    【讨论】:

    • 看起来不错。但是如果我需要使用不同的参数多次调用sum 并且每次都得到不同的结果怎么办? (这就是我传统上避免使用存根的原因)
    • 如果stub 的返回值发生变化,那么测试可能在不同的context 块中,在这种情况下,您可以使用lets 来减少before 块的重复.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 2012-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多