Как проверить IO с помощью rspec для HighLine gem? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть класс:

class Asker

  def initialize
    @cli = HighLine.new
  end 

  def exit_or_continue
    answer = @cli.ask "Type 'quit' to exit at any time, Press 'Enter' to continue"
    exit(0) if answer == 'quit'
  end
end

Как я могу проверить метод exit_or_continue?

1 Ответ

0 голосов
/ 27 февраля 2019

Насколько я понимаю, вы хотите протестировать метод exit_or_continue в зависимости от ввода пользователя.В этом методе есть две основные важные вещи.Одним из них является пользовательский ввод, который @cli.ask делает, а другим является exit метод, который завершает программу, если пользовательский ввод quit.

Чтобы проверить эти потоки, нам нужно использовать метод Kernel.exit и HighLine#ask.Во-первых, мы переопределяем метод Kernel.exit внутри экземпляра класса Asker.Модуль Kernel входит в класс Object, и каждый класс неявно расширяет класс Object в ruby.Таким образом, наш класс Asker по умолчанию имеет методы Kernel.

Почему мы заглушаем метод exit внутри экземпляра класса Asker, это может привести к неожиданным проблемам, если мы заглушим его глобально(В ядре).Более того, если мы не заглушим этот метод, rspec завершит работу, а остальные тесты не будут запущены.

Во-вторых, нам нужно заглушить HighLine#ask метод, который ожидает ввода от клиента.HighLine#ask - это метод, который использует Kernel.gets под капотом.Подставляя этот метод, мы в основном говорим: , пожалуйста, верните это значение и не ждите ввода пользователя. '.Другими словами, с @cli.stub(ask: 'quit') это вернет quit или что угодно, без каких-либо подсказок.

Так что я думаю, что следующий тест удовлетворит вашу потребность.Если у вас возникнут какие-либо проблемы, пожалуйста, не стесняйтесь оставлять комментарии.

RSpec.describe Asker do

  describe '#exit_or_continue' do
    before do
      @asker = Asker.new
      @cli = @asker.instance_variable_get('@cli')
      @asker.stub(exit: true) # We override Kernel.exit method inside asker instance
    end

    context 'when user input is quit' do
      it 'returns true' do
        @cli.stub(ask: 'quit') # We stub HighLine#ask method to return quit on behalf of the user.
        expect(@sker.exit_or_continue).to be(true)
      end
    end
    context 'when user is input is NOT quit' do
      it 'returns nil' do
        @cli.stub(ask: 'invalid response') # We stub HighLine#ask method to return invalid response on behalf of the user.
        expect(@sker.exit_or_continue).to be_nil
      end
    end
  end
end
...