【问题标题】:Rspec - Stubbing gets.chomp out of the constructorRspec - 从构造函数中存根gets.chomp
【发布时间】:2015-04-16 09:04:16
【问题描述】:

我正在用 Ruby 编写 Mastermind 游戏,在“游戏”类的构造函数中,我想使用 gets.chomp 向用户询问其名称。很简单,但是我遇到麻烦的地方是在 RSpec 中测试这个类时,但我似乎无法正确地排除“gets”和“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

我还尝试将存根放入“之前”和“让”块中,但似乎没有任何效果。任何帮助表示赞赏!

【问题讨论】:

  • 虽然这当然是可能的,但您应该考虑重构您的代码。如果您可以在不存根getsputs 的情况下初始化Game,那会不会容易得多?
  • 我认为这是最好的方法,是的,谢谢!下面的答案虽然很可能是正确的,但对于我正在做的事情来说似乎太复杂了。

标签: ruby rspec


【解决方案1】:

我有一个方法可以捕获标准输入和标准输出,以帮助在以下情况下进行测试:

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

现在,假设我想测试一个与标准输入/标准输出交互的方法:

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

【讨论】:

  • 谢谢!这对于我正在做的事情来说似乎太复杂了(我有点理解,但不是 100%),所以我想我会接受另一个人的评论,把 puts + gets 从构造函数中取出并将它们放入一种不同的方法,应该更容易存根。
  • @FrankPeelen 是的,这是个好建议。当您别无选择时存根getsputs(例如:您需要测试现有的遗留代码)。当我明确必须使用标准输入/输出时,我个人使用这种技术为 codegolf.stackexchange.com 编写答案。
猜你喜欢
  • 2010-09-23
  • 2019-09-21
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
相关资源
最近更新 更多