写入测试以接受来自命令行的输入

时间:2012-09-18 13:34:36

标签: ruby unit-testing rspec io rspec2

我对rspec很新,并希望在rspec中编写测试,以便从Ruby中的命令行获取输入。我该怎么办呢?另外,解释测试。感谢

2 个答案:

答案 0 :(得分:2)

使用模拟:

STDIN.should_receive(:read).and_return("your string")

我也喜欢here描述的方法。我认为最后一个更适合你的情况。

答案 1 :(得分:2)

一般方法是使这种对象可以交换。 在您的情况下,gets会隐式调用$stdin。所以你可以选择 名为“输入”的参数默认为$stdin并且调用它。

这是一个简单的计算器示例,它接受一些输入并返回结果。

class Calculator
  def initialize input = $stdin
    @input = input
  end

  def process
    eval @input.gets
  end
end

现在您可以运行puts Calculator.new.process,输入1 + 2,您会看到3

您不需要任何特殊工具来测试它,因为您可以轻松传递IO对象 并在你的测试中写到它。 IO.pipe是一个很好的选择:

describe "Calculator" do
  before do
    reader, @writer = IO.pipe
    @calc = Calculator.new(reader)
  end

  it "can sum up two numbers" do
    @writer.puts "1 + 2"
    result = @calc.process
    result.should eq(3)
  end
end

您也可以使用StringIO而不是真正的IO,并且不需要类似UNIX的环境。 虽然每次编写时都需要回放流。

require "stringio"

describe "Calculator" do
  before do
    @input = StringIO.new
    @calc = Calculator.new(@input)
  end

  it "can sum up two numbers" do
    @input.puts "1 + 2"
    @input.rewind
    result = @calc.process
    result.should eq(3)
  end
end

这种方法与短截的优点是不太脆弱的测试和更好的设计。 测试不那么脆弱,因为如果您决定更改实现并使用getc 而不是获取(逐个读取字符),例如,您不需要更改测试。 设计更好,因为现在您可以轻松地从不同的来源提供命令 例如文件Calculator.new(File.open("calculated_list.txt"))。或者你的假IO 可以在你的测试中使用!