【问题标题】:Write test for accepting input from command line编写接受命令行输入的测试
【发布时间】:2012-09-10 18:48:06
【问题描述】:

我对 rspec 还很陌生,想在 rspec 中编写测试,以便从 Ruby 中的命令行获取输入。我该怎么做?另外,解释一下测试。谢谢

【问题讨论】:

  • 你想测试给定的标准输入或命令行参数吗? ruby foo.rb --argument1 --argument2?你能举一个你想要测试的例子吗?
  • a = 得到某种请求。我实现了这个@life.stub(:gets) { "5" } (next line) @life.input.should == 5,但我不知道这是不是正确的做法。

标签: ruby unit-testing rspec io rspec2


【解决方案1】:

通过使用模拟:

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

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

【讨论】:

    【解决方案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 可以在你的测试中使用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多