Rspec - 从构造函数中删除gets.chomp

时间:2015-04-16 09:04:17

标签: ruby rspec

我正在用Ruby编写一个Mastermind游戏,并在该类的构造函数中使用Game' Game'我想使用gets.chomp来询问用户的名字。很容易,但是我遇到麻烦的地方是在RSpec中测试这个类,但我似乎无法正确地删除'得到'和' puts',因为它们在构造函数中不是常规方法。

class Game
  def initialize
    puts "Please enter your name:"
    @player = Player.new(gets.chomp)
  end
end

describe Game do
  Game.stub(:gets).and_return("Create Code AI")
  Game.stub(:puts)
  subject(:game) { Game.new }

  describe "#new" do
    its("player.name") { eql("Create Code AI") }
  end
end

class Player
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

我还试过把短信放到'之前。和'让'阻止其他事情,但似乎没有任何作用。任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

我有一个捕获stdin和stdout的方法来帮助测试这些情况:

require 'stringio'

module Kernel
  def capture_stdout(console_input = '')
    $stdin = StringIO.new(console_input)
    out = StringIO.new
    $stdout = out
    yield
    return out.string.strip
  ensure
    $stdout = STDOUT
    $stdin = STDIN
  end
end

现在,让我们假设我想测试一个与stdin / stdout交互的方法:

def greet
  name = gets
  puts "Welcome, #{name}!"
end

我会写下面的测试:

require 'rspec/autorun'

RSpec.describe '#say_name' do
  it 'prints name correctly' do
    input = 'Joe'
    result = capture_stdout(input) do
      greet
    end

    expect(result).to eql 'Welcome, Joe!'
  end
end

我提供了上面的示例来说明如何测试控制台输入和输出。

在您的情况下,测试可能如下所示:

describe Game do
  subject(:game) do
    capture_stdout('Create Code AI') { return Game.new }
  end

  describe "#new" do
    its("player.name") { eql("Create Code AI") }
  end
end

注意:为了实现此目的,#player应该是Game的可访问成员。因此,您可能希望将其添加到Game类:

attr_reader :player