rspec模拟:验证它的“应该”方法的期望?

时间:2009-10-18 01:47:27

标签: mocking rspec assertions

我正在尝试使用rspec的模拟来设置我可以在“应该”方法中验证的期望......但我不知道如何做到这一点...当我调用.should_receive方法时mock,它会在before:all方法退出时立即验证预期的调用。

这是一个小例子:

describe Foo, "when doing something" do
 before :all do
  Bar.should_recieve(:baz)
  foo = Foo.new
  foo.create_a_Bar_and_call_baz
 end

 it "should call the bar method" do
  # ??? what do i do here?
 end
end

如何验证'it'应该''方法中的预期呼叫?我需要使用mocha或其他模拟框架而不是rspec吗?或??? ???

5 个答案:

答案 0 :(得分:8)

我将对此采取另一种措施,因为从最初的答案和答案中可以清楚地看出,对于你想要完成的事情存在一些困惑。如果这更接近你想要做的事,请告诉我。

describe Foo, "when frobbed" do
  before :all do
    @it = Foo.new

    # Making @bar a null object tells it to ignore methods we haven't 
    # explicitly stubbed or set expectations on
    @bar = stub("A Bar").as_null_object
    Bar.stub!(:new).and_return(@bar)
  end

  after :each do
    @it.frob!
  end

  it "should zap a Bar" do
    @bar.should_receive(:zap!)
  end

  it "should also frotz the Bar" do
    @bar.should_receive(:frotz!)
  end
end

顺便说一下,虽然它有效但我不是Bar.stub!(:new)模式的忠实粉丝;我通常更喜欢通过可选参数传递协作者,例如@it.frob!(@bar)。如果未给出明确的参数(例如在生产代码中),则可以默认协作者:def frob!(bar=Bar.new)。这使得测试对内部实现的限制更少。

答案 1 :(得分:1)

作为一般规则,你绝不应该在before区块中提出期望。 before块用于设置跨多个示例(it块)共享的状态。将期望放在示例本身中。 E.g:

describe Foo, "when doing something" do
  before :all do
   @foo = Foo.new
  end

  it "should call the bar method" do
    Bar.should_recieve(:baz)
    @foo.create_a_Bar_and_call_baz
  end
end

我通常会尝试让describe块描述特定的状态(例如describe Car, "given a full tank of gas"),而不是描述某个操作。

答案 2 :(得分:1)

should_receive方法用于设置模拟对象,以便在调用方法时返回特定内容。这是一个例子:

Bar.should_recieve(:baz).with.({:arg1 => 'this is arg1', :arg2 => 'this is arg2'}).and_return(true)

通常,使用BDD,您需要测试应用的行为。测试调用哪些方法以构建正确的行为是无关紧要的。如果有一天您决定删除baz方法,即使应用程序的行为不会发生变化,您也必须更新测试。

我认为你试图以一种不适合的方式使用should_receive。

答案 3 :(得分:1)

我知道这是一个古老的对话,但万一有人仍然需要一个正确的答案,在这里我写一个关于如何验证rpec模拟观众的例子:

require 'spec'
require 'spec/mocks'
include Spec::Mocks::ExampleMethods

o = mock('object')
o.should_receive(:respond_to?).once

space = Spec::Mocks::Space.new
space.add o

# here we should invoke methods, o.respond_to?:foo for instance

space.verify_all

欢呼声

答案 4 :(得分:0)

也许我只是简单地看待它,但是,您是否需要多次验证与Bar的交互?如果是的话,好的,但我不确定。换句话说,你在混合上下文吗?

如果没有,那么它不是真正的背景,因为它是观察的一部分,这将使它自然属于它的阻挡。