【问题标题】:how to yield different values for different calls with rspec如何使用 rspec 为不同的调用产生不同的值
【发布时间】:2014-12-18 01:25:31
【问题描述】:

我正在尝试以与 and_return 相同的方式使用 and_yield。我希望它每次被调用时产生一个值......但是每次被调用时它都会产生 TWICE。

这个人为的例子说明了问题

class Yielder
  @@blocks = []
  def self.yielder; end
  def self.blocks= b; @@blocks << b; end
  def self.blocks; @@blocks; end
end

describe Yielder do
  it 'should yield twice' do
    allow(Yielder).to receive(:yielder).and_yield(:foo).and_yield(:bar)

    2.times do
      Yielder.yielder do |y|
        Yielder.blocks = y
      end
    end

    expect(Yielder).to have_received(:yielder).twice
    expect(Yielder.blocks).to eq [:foo, :bar]
  end
end

rspec 结果...

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

我是不是用错了?

【问题讨论】:

  • 根据docs,这是预期的行为。
  • 使用与and_return相同的语法,行为不同。我想以同样的方式测试and_yield
  • 我怀疑实际上不支持你想要的:-(我的回答假设传递一个块会起作用,但实际上该块是在代码中运行的,它的结果被忽略了(!)

标签: ruby rspec


【解决方案1】:

正如建议的那样,and_yield 的工作方式与and_return 的工作方式不同。但是,如果您想要这种行为,您可以执行以下操作:

describe Yielder do
  it 'should yield twice' do
    values = [:foo, :bar]
    allow(Yielder).to receive(:yielder) do |&block|
      block.call(values.shift)
    end

    2.times do
      Yielder.yielder do |y|
        Yielder.blocks = y
      end
    end

    expect(Yielder).to have_received(:yielder).twice
    expect(Yielder.blocks).to eq [:foo, :bar]
  end
end 

【讨论】:

  • 请注意,您也可以使用expect() 执行此操作,但您需要使用twiceexactly(3).times 等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2012-09-20
  • 1970-01-01
相关资源
最近更新 更多