存根'得到'在红宝石中多次

时间:2015-06-08 06:24:36

标签: ruby rspec

我有一个简单的问题,问Ruby脚本:

def ask question 
  while true
    puts question
    reply = gets.chomp.downcase

    return true if reply == 'yes' 
    return false if reply == 'no'

    puts 'Please answer "yes" or "no".' 
  end
end

puts(ask('Do you like eating tacos?'))

我正在测试它

describe 'ask' do
  before do
    stub(:puts).with('anything')
    stub(:puts).with('Please answer "yes" or "no".')
    stub(:gets).and_return 'yes'
  end
  it 'returns true when you say yes' do
    expect(ask('anything')).to be true
  end
  it 'returns false when you say no' do
    stub(:gets).and_return 'no'
    expect(ask('anything')).to be false
  end
end

我以前一直在尝试使用RSpec 3语法和

之类的代码
allow(STDIN).to receive(:gets).and_return 'yes'
allow(Kernel).to receive(:gets).and_return 'yes'
allow(IO).to receive(:gets).and_return 'yes'

和其他变体,但这些都没有奏效,只是给我一些错误:

undefined method `chomp' for nil:NilClass

我对RSpec 2语法运气好,所以我启用了它,并且几乎完成了上述工作。问题是这一行:puts(ask('Do you like eating tacos?'))。如果这被注释掉,一切都很好,但是当它出现时我收到了这个错误:

Errno::ENOENT: No such file or directory @ rb_sysopen

然后现在

undefined method格格'为零:NilClass`

所以我觉得我可以得到'在从RSpec调用的方法中,但是如果从RSpec正在测试的ruby文件中调用使用它的方法则不行。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

啊哈,我想我找到了解决办法!

诀窍似乎是allow_any_instance_of(Kernel).to receive(:gets).and_return 'yes'并在应用程序代码被拉入之前在前一个块中调用 - 如下所示:

describe 'ask' do
  before do
    stub(:puts).with('anything')
    stub(:puts).with('Please answer "yes" or "no".')
    stub(:gets).and_return 'yes'
    allow_any_instance_of(Kernel).to receive(:gets).and_return 'yes'
    require './lib/ask.rb'
  end
  it 'returns true when you say yes' do
    expect(ask('anything')).to be true
  end
  it 'returns false when you say no' do
    allow_any_instance_of(Kernel).to receive(:gets).and_return 'no'
    expect(ask('anything')).to be false
  end
end