如何测试有序和x次的rspec模拟?

时间:2016-09-19 21:30:11

标签: ruby rspec

我有一个递归方法,我需要测试方法调用的顺序,以及调用它们的次数。我遇到的问题是,这些方法调用备用。例如......

it 'call methods in order' do
  expect(@instance).to have_received(:foo).ordered
  expect(@instance).to have_received(:bar).ordered
  expect(@instance).to have_received(:foo).ordered
  expect(@instance).to have_received(:bar).ordered
  expect(@instance).to have_received(:foo).ordered
  expect(@instance).to have_received(:bar).ordered
end

因为

而失败
expected: 1 time with any arguments
received: 3 times with any arguments
被调用3次的{p> foobar是正确的,但我如何交替测试它们?

2 个答案:

答案 0 :(得分:1)

这样的事情应该有效:

it 'call methods in order' do
  @method_calls = []

  allow(@instance).to receive(:foo) do
    @method_calls << :foo
  end

  allow(@instance).to receive(:bar) do
    @method_calls << :bar
  end

  ...

  expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar])     
end

这是我尝试过的最小化测试,它充分展示了这一点:

require "rspec"

class MyClass
  def bar
  end

  def foo
  end

  def foobar
    foo
    bar
    foo
    bar
    foo
    bar
  end
end

describe "Foo" do
  describe "#foobar" do
    let(:instance) { MyClass.new }

    it "alternately calls foo/bar" do
      @method_calls = []

      allow(instance).to receive(:foo) do
        @method_calls << :foo
      end

      allow(instance).to receive(:bar) do
        @method_calls << :bar
      end

      instance.foobar

      expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar])
    end
  end
end

运行此规范会通过,但删除(比方说)foobar方法中的一个方法调用会导致此错误:

F

Failures:

  1) Foo #foobar alternately calls foo/bar
     Failure/Error: expect(@method_calls).to eq([:foo, :bar, :foo, :bar, :foo, :bar])

       expected: [:foo, :bar, :foo, :bar, :foo, :bar]
            got: [:bar, :foo, :bar, :foo, :bar]

       (compared using ==)

       Diff:
       @@ -1,2 +1,2 @@
       -[:foo, :bar, :foo, :bar, :foo, :bar]
       +[:bar, :foo, :bar, :foo, :bar]
     # ./rspec_test.rb:38:in `block (3 levels) in <top (required)>'

Finished in 0.01517 seconds (files took 0.07714 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./rspec_test.rb:25 # Foo #foobar alternately calls foo/bar

希望这是有道理的。

答案 1 :(得分:0)

你应该封装方法的递归部分,存根其他所有内容,然后通过黑盒方法测试该方法(即输入 - >输出)。