3

我正在尝试使用 rspec 的模拟来设置我可以在它“应该”方法中验证的期望......但我不知道该怎么做......当我在模拟上调用 .should_receive 方法时,它只要 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

如何验证“应该”方法中的预期调用?我需要使用 mocha 或其他模拟框架而不是 rspec 吗?或者 ???

4

5 回答 5

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). 这使测试较少受到内部实现的约束。

于 2009-10-18T19:03:55.187 回答
1

作为一般规则,你永远不应该把期望放在一个before块中。 before块用于设置在多个示例(it块)之间共享的状态。将期望放在示例本身中。例如:

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"),而不是描述一个动作。

于 2009-10-18T01:56:06.113 回答
1

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

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

通常,使用 BDD,您希望测试应用程序的行为。测试调用了哪些方法来构建正确的行为是无关紧要的。如果有一天您决定删除 baz 方法,您将不得不更新您的测试,即使您的应用程序的行为不会改变。

我认为您正在尝试以一种不应该像它那样工作的方式使用 should_receive。

于 2009-10-18T14:35:04.917 回答
1

我知道这是一个古老的对话,但以防万一有人仍然需要一个正确的答案,我在这里写了一个关于如何验证 rpec mocks spectations 的示例:

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

干杯

于 2010-05-15T19:17:12.147 回答
0

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

如果不是,那么它就不是真正的上下文,而是观察的一部分,这将使它自然地属于 it 块。

于 2009-10-18T04:03:45.350 回答