RSpec:stub里面让

时间:2014-07-26 02:14:47

标签: rspec

这可能吗?

示例:

let(:codes) do
  [double.stub(:msg => 'foo'), double.stub(:msg => 'bar')]
end

expect(codes[0].msg).to eq('foo')
expect(codes[1].msg).to eq('bar')

但它引发了以下错误:

NoMethodError:
       undefined method `msg' for {:msg=>"foo"}:Hash

let(:mouse) do
  [
     double.stub(:msg).and_return('foo'),
     double.stub(:msg).and_return('bar')
  ]
end

[nil,nil]返回mouse

任何帮助?

2 个答案:

答案 0 :(得分:1)

问题是,至少对于RSpec 3,stub方法本身不会返回双重存根。在您的情况下,它返回传递给它的哈希值,如下所示:

describe 'RSpecs double behavior' do
  describe '#stub' do
    it 'returns the hash passed into it' do
      expect(double.stub(msg: foo)).to eq({msg: 'foo'})
    end
  end
end

这似乎与RSpec 2.3 documentation相反,但RSpec 3.0 documentation对此问题保持沉默并基于this discussion,我认为这种行为是故意的。

请参阅Myron Marston关于避免使用stub并完全依赖double的替代方案的答案。

顺便说一句,我认为在这些问题中,在示例中使用有效的RSpec语法会很有帮助。在这种情况下,您省略了所需的describeit方法。

答案 1 :(得分:1)

  

这似乎与RSpec 2.3文档相反

很抱歉,那里的2.3文档错了:(。

  

RSpec 3.0文档对此事保持沉默,基于此讨论,我收集的行为是故意的。

这是故意的,因为stub旨在支持流畅的界面(withand_returnand_raise等,所以它需要返回一个消息期望。如果您想打开文件,我们欢迎PR改进文档:)。

无论如何,您可以将方法名称/返回值的哈希值传递给double,因此根本不需要使用stub

describe 'stack overflow question' do
  let(:codes) do
    [double(msg: 'foo'), double(msg: 'bar')]
  end

  it "let's you call stub within let" do
    expect(codes[0].msg).to eq('foo')
    expect(codes[1].msg).to eq('bar')
  end
end

double上的文档提到了这一点: