rspe c - как проверить, нет ли ввода в ruby - PullRequest
2 голосов
/ 29 января 2020

Я пытаюсь написать spe c, чтобы проверить, как мой код будет реагировать, когда пользователь просто нажимает клавишу «Ввод», т.е. не вводит никаких данных, просто нажимает «Ввод».

Сам код будет l oop, пока не будет введена правильная запись, но я не могу получить spe c для его проверки. Приведенный ниже код является примером как класса, так и объекта spe c.

. Обратите внимание, что в spe c я пытался заменить раздел «запрашивать повторно» на with_input (''), но это просто кажется зависает (или l oop)

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

--- И спец c

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

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Просто Мими c Л oop:

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
0 голосов
/ 29 января 2020

Когда вы заменяете его на

output = ask_for_number_with_input("")

, оно зацикливается навсегда, потому что именно так говорит ваш код, вы хотели, чтобы оно l oop, пока не получит число> 6, что никогда не произойдет , @input.gets.to_i просто будет продолжать возвращать 0, потому что IO#gets

Возвращает ноль, если вызывается в конце файла.

Чтобы заставить его перестать зависать, просто присвойте ему другое значение:

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

и теперь оно проходит

...