Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何使用ordered和x时间测试rspec模拟?_Ruby_Rspec - Fatal编程技术网

Ruby 如何使用ordered和x时间测试rspec模拟?

Ruby 如何使用ordered和x时间测试rspec模拟?,ruby,rspec,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)

我有一个递归方法,我需要测试方法调用的顺序,以及调用的次数。我的问题是,这些方法调用交替。例如

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

foo
bar
被调用3次是正确的,但是我如何交替测试它们呢?

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

像这样的方法应该会奏效:

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

希望这有道理。

我不明白。。。你能详细说明/展示一个例子吗?这非常有效。。。我有一些类似的功能,但是在
expect
调用中添加了一个块,而不是
allow
调用。。。。非常感谢你!很高兴它成功了!我的想法基于我写的一篇关于在rspec中模拟相互依赖的帖子,如果您感兴趣的话:
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
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