Тестирование попадает в rspec (пользовательский ввод) - PullRequest
0 голосов
/ 28 ноября 2018

В моем классе есть такой метод #run, который до сих пор только для тестирования:

def run
    puts "Enter 'class' to create a new class."
    input = $stdin.gets.chomp
    binding.pry

И в тестах пока у меня есть

  allow($stdin).to receive(:gets).and_return 'class'
  cli.run

Делая это таким образом, я могу видеть в сеансе pry, что input было установлено на 'class', как и предполагалось.

Есть ли способ сделать это без добавления $stdin к моемувызывать gets в самом моем методе?то есть input = gets.chomp

Я пробовал allow(cli.run).to receive(:gets).and_return 'class' Но тогда в сеансе pry input равен первой строке файла спецификации!

1 Ответ

0 голосов
/ 29 ноября 2018

Вы можете избежать этого следующим образом:

def run
  puts "Enter 'class' to create a new class."
  input = gets.chomp
end

describe 'gets' do 
  it 'belongs to Kernel' do 
    allow_any_instance_of(Kernel).to receive(:gets).and_return('class')
    expect(run).to eq('class')
  end
end

Метод gets фактически принадлежит модулю Kernel.(method(:gets).owner == Kernel).Поскольку Kernel входит в Object и почти все объекты ruby ​​наследуются от Object, это будет работать.

Теперь, если run является методом экземпляра, ограниченным в Class, я бы порекомендовал определить область действиянемного больше заглушки, что:

class Test
  def run
    puts "Enter 'class' to create a new class."
    input = gets.chomp
  end
end

describe 'gets' do 
  it 'can be stubbed lower than that' do 
    allow_any_instance_of(Test).to receive(:gets).and_return('class')
    expect(Test.new.run).to eq('class')
  end
  # or even 
  it 'or even lower than that' do 
    cli = Test.new
    allow(cli).to receive(:gets).and_return('class')
    expect(cli.run).to eq('class')
  end
end

Пример

...