[英]rspec - how to test for nil input in ruby
我正在嘗試編寫一個規范來測試當用戶只是按下“Enter”鍵時我的代碼將如何反應,即不輸入任何數據只是按下“Enter”。
代碼本身將循環,直到創建有效條目,但我無法獲得規范來對其進行測試。 下面的代碼是類和規范的示例。
請注意,在規范中,我嘗試用 with_input('') 替換“重復詢問”部分,但它似乎掛起(或循環)
class Example
def initialize(input: $stdin, output: $stdout)
@input = input
@output = output
end
def ask_for_number
@output.puts "Input an integer 5 or above"
loop do
input = @input.gets.to_i
return true if input >= 5
@output.puts "Invalid. Try again:"
end
end
end
--- 和規格
require 'stringio'
require_relative 'Example'
describe Example do
context 'with input greater than 5' do
it 'asks for input only once' do
output = ask_for_number_with_input(6)
expect(output).to eq "Input an integer 5 or above\n"
end
end
context 'with input equal to 5' do
it 'asks for input only once' do
output = ask_for_number_with_input('5')
expect(output).to eq "Input an integer 5 or above\n"
end
end
context 'with input less than 5' do
it 'asks repeatedly, until a number 5 or greater is provided' do
output = ask_for_number_with_input(2, 3, 6)
expect(output).to eq <<~OUTPUT
Input an integer 5 or above
Invalid. Try again:
Invalid. Try again:
OUTPUT
end
end
def ask_for_number_with_input(*input_numbers)
input = StringIO.new(input_numbers.join("\n"))
output = StringIO.new
example = Example.new(input: input, output: output)
expect(example.ask_for_number).to be true
output.string
end
end
當你用它替換它時
output = ask_for_number_with_input("")
它永遠循環,因為這就是你的代碼告訴它做的,你希望它循環直到它收到一個大於 6 的數字,這永遠不會發生, @input.gets.to_i
將繼續返回0
因為IO#gets
如果在文件末尾調用,則返回 nil。
要讓它停止掛起,只需給它另一個值:
it 'asks repeatedly, until a number 5 or greater is provided' do
output = ask_for_number_with_input("", "", 6)
expect(output).to eq <<~OUTPUT
Input an integer 5 or above
Invalid. Try again:
Invalid. Try again:
OUTPUT
end
現在它過去了
只需模仿循環:
require "spec_helper"
describe 'Example' do
let(:entered_value) { 6 }
let(:stdin) { double('stdin', gets: entered_value) }
let(:stdout) { double('stdout') }
subject { Example.new(input: stdin, output: stdout) }
describe '#ask_for_number' do
before(:each) do
allow(subject).to receive(:loop).and_yield
end
context 'pressed enter without any input' do
let(:entered_value) { nil }
it 'prints invalid output' do
expect(stdout).to receive(:puts).with("Input an integer 5 or above")
expect(stdout).to receive(:puts).with("Invalid. Try again:")
subject.ask_for_number
end
end
end
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.