Rspec测试用例不起作用

时间:2014-07-26 16:39:27

标签: ruby rspec

我可能犯了一些愚蠢的错误但是通过运行rake显示了这个

rake

由于无限循环,它无限运行直到我停止它。

文件夹结构如下:

folder

calculator.rb

class Calculator

    attr_accessor :result

    def initialize
        @result = 0.0
    end

    def add(param)
        @result += param
    end

    def subtract(param)
        @result -= param
    end

    def multiply(param)
        @result *= param
    end

    def divide(param)
        @result /= param
    end

    def cancel
        @result = 0.0
    end
end

class CommandProcessor
    attr_accessor :input
    attr_accessor :operation
    attr_accessor :calculator

    def parser
        calculator = Calculator.new
        while true
            input = gets.to_s.chomp
            operation = input.split(' ')[0]
            param = input.split(' ')[1]
            if operation.eql? 'exit'
                exit
            elsif operation.eql? 'add'
                calculator.add(param.to_f)
                puts calculator.result
            elsif operation.eql? 'subtract'
                calculator.subtract(param.to_f)
                puts calculator.result
            elsif operation.eql? 'multiply'
                calculator.multiply(param.to_f)
                puts calculator.result
            elsif operation.eql? 'divide'
                calculator.divide(param.to_f)
                puts calculator.result
            elsif operation.eql? 'cancel'
                calculator.cancel
                puts calculator.result
            else
                puts "invalid op"
            end
        end
    end
end

command = CommandProcessor.new
command.parser

calculator_spec.rb

require 'spec_helper'
require "calculator.rb"

describe "CommandProcessor" do
    it "will exit on input exit" do
        @cmd = CommandProcessor.new
        @cmd.stub!(:gets).and_return("add 3\n")
        @cmd.parser
        expect(@cmd.calculator.result).to eq 3
    end
end

describe "Calculator" do
    it "will add a number" do
        calculator = Calculator.new
        expect(calculator.add 2).to eq 2.0
        expect(calculator.add 2.0).to eq 4.0
    end

    it "will subtract a number" do
        calculator = Calculator.new
        expect(calculator.subtract 2).to eq -2.0
        expect(calculator.subtract 2.0).to eq -4.0
    end

    it "will multiply a number" do
        calculator = Calculator.new
        expect(calculator.multiply 2).to eq 0.0
        expect(calculator.multiply 2.0).to eq 0.0
    end

    it "will divide a number" do
        calculator = Calculator.new
        expect(calculator.divide 2).to eq 0.0
        expect(calculator.divide 2.0).to eq 0.0
    end

    it "will make result zero on cancel" do
        calculator = Calculator.new
        calculator.cancel
        expect(calculator.result).to eq 0.0
    end
end

我是否错误地构建了代码或者我的测试错了?代码工作正常但不是测试用例。

1 个答案:

答案 0 :(得分:2)

无限循环的罪魁祸首是你自己在CommandProcessor#parser中介绍的那个。

我认为问题在于你在你的对象上存在gets,但实际上,它是在Kernel上定义的,所以如果你要在任何地方存根,那就是那里。这意味着gets可能会返回您的解析器无法理解的某种废话,这会导致您看到invalid op的无限循环。在这种情况下打印无效操作可能是有用的(即将puts "invalid op"更改为puts "invalid op: #{operation}"。)

值得注意的是,即使您的存根已经工作,并且您不断获取add 3而不是垃圾数据,您的编程仍将永远循环,因为解析器永远不会收到exit,需要摆脱循环。

在我看来,这个问题表明了另一个问题:你试图一次性测试两件事:解析器和IO。我建议更改您的接口,以便您的CommandProcessor.parse接受一个字符串,解析它,并从内部Calculator实例返回结果。然后测试几乎变得微不足道,这就是我们想要的(没有人想要太难思考)。