我是使用RSpec和Ruby的单元测试的新手,我有一个问题,如何测试我的代码是否使用gets
方法,但没有提示用户输入。
这是我要测试的代码。这里没什么了不起的,只是一个简单的单线。
my_file.rb
My_name = gets
这是我的规格。
require 'stringio'
def capture_name
$stdin.gets.chomp
end
describe 'capture_name' do
before do
$stdin = StringIO.new("John Doe\n")
end
after do
$stdin = STDIN
end
it "should be 'John Doe'" do
expect(capture_name).to be == 'John Doe'
require_relative 'my_file.rb'
end
end
现在这个规范有效,但是当我运行代码时,它会提示用户输入。我不希望它那样做。我想简单地测试是否正在调用gets方法并且可能模拟用户输入。不确定如何在RSpec中实现这一点。在Python中我会使用unittest.mock在RSpec中有类似的方法吗?
提前致谢!
答案 0 :(得分:4)
以下是您如何使用返回值存储gets
。
require 'rspec'
RSpec.describe do
describe 'capture_name' do
it 'returns foo as input' do
allow($stdin).to receive(:gets).and_return('foo')
name = $stdin.gets
expect(name).to eq('food')
end
end
end
Failures:
1) should eq "food"
Failure/Error: expect(name).to eq('food')
expected: "food"
got: "foo"
(compared using ==)
要测试是否正在调用某些内容(例如函数),您可以使用expect($stdin).to receive(:gets).with('foo')
来确保使用正确的args调用它(一次)。此方案中的期望行必须在name = $stdin.gets
之前。