RSpec:在没有测试提示的情况下模拟用户输入(通过获取)

时间:2018-04-11 15:58:16

标签: ruby rspec

我正在采用TDD第一种方法对游戏进行编码,并因为测试一直停在用户输入(repo is here)而陷入困境。

我希望测试模拟用户输入而不是提示输入,因为我设置了一些let个关键字并试图通过gets.chomp来考虑用户输入。

这是游戏提示用户输入的地方:

game.rb

module ConnectFour
  class Game
    def start_game
      puts 'Welcome to Connect Four.'
      puts "Enter name of player 1 (red)"
      player1name = gets.chomp
      player1 = Player.new(player1name)
    end
  end
end 

这是测试代码:

game_spec.rb

require 'spec_helper'

module ConnectFour
  describe Game do
    let(:game) { Game.new }
    let(:player1name) { 'Bob' }
    let(:player1) { Player.new(player1name) }

    describe 'Instantiate game play objects' do

      describe 'Create player 1' do
        it 'Provide player 1 name' do
          allow_any_instance_of(Kernel)
          .to receive(:gets)
          .and_return(player1name)
        end
        it 'Instantiate player 1' do
          expect(player1.name).to eq player1name
        end
      end
    end # describe 'Instantiate game play objects'
  end # Describe 'Game'
end

到目前为止,我已尝试将gets.chomp封装在自己的方法recommended here中,但这没有效果。我也尝试在Ruby代码中为$stdin前缀gets.chomp语句,但是,这是非常无用的。我最近在这里问过similar question并认为我已经理解了如何模拟用户输入,但显然不是......任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

使用allow_any_instance_of(Object)代替Kernel。模块内核包含在Object中。内核实际上并未实例化,因为它是一个模块。

有点小问题,但是如果你用stubbed返回结尾\n的strinng那么它会更准确,否则你可以从测试的函数中删除chomp并且测试仍然会通过

可重现的示例

require 'rspec'
require 'rspec/expectations'

test_case = RSpec.describe "" do
  it "" do
    allow_any_instance_of(Object).to receive(:gets).and_return "something\n"
    puts gets.chomp
  end
end

test_case.run