计时器 RSpec 测试 Ruby

Timer RSpec Test Ruby

我正在尝试解决 TestFirst Ruby 中的计时器问题。

我正确地获得了前两个标准,但在测试时间 = 12 秒时,第三个标准不起作用。它看起来不像 Ruby 正在读取时间 = 12 秒。

这些代码显然很懒惰,而且没有优化。我也确实尝试了填充方法,但测试从未奏效。我将填充方法定义为

def padded(num)
 if num<=9
   return "0"<<num.to_s
 else 
   return num.to_s
 end
end

如果有人能告诉我如何正确设置,那就太好了,因为这可能是问题所在。

这是我的完整代码:

class Timer
#initialization of seconds
def seconds
    return 0
end

#seconds= method
def seconds=(time)
    @seconds = time_string(time)
end

#time_string method

def time_string(time=0)
    #format of hour:minute:second
    #minute must be less than 59 (or 59*60 seconds), otherwise it will convert to hour
    minute = time/60    #note that this is integer math, so it will take the minute and not the remainder
    hour = minute/60
    remainder_seconds = time%60
    if time<=9
        return "00:00:0" << time.to_s
    elsif time>9 && time<=60
        return "00:00:" << time.to_s
    elsif time>60 && time<=9*60 #9 minutes and greater than 1 min
        #ensuring double XX seconds or 0X seconds (this would be easier to use the padded method)
        if remainder_seconds >9
            remainder_seconds_sd = remainder_seconds.to_s
        else
            remainder_seconds_sd = "0" << remainder_seconds.to_s
        end

        return "00:0" << minute.to_s << ":" << remainder_seconds_sd
    end
end

end

RSpec 下面:

require '09_timer'

describe "Timer" do
  before(:each) do
    @timer = Timer.new
  end

  it "should initialize to 0 seconds" do
    @timer.seconds.should == 0
  end

  describe 'time_string' do
    it "should display 0 seconds as 00:00:00" do
      @timer.seconds = 0
      @timer.time_string.should == "00:00:00"
    end

    it "should display 12 seconds as 00:00:12" do
      @timer.seconds = 12
      @timer.time_string.should == "00:00:12"
    end

    it "should display 66 seconds as 00:01:06" do
      @timer.seconds = 66
      @timer.time_string.should == "00:01:06"
    end

    it "should display 4000 seconds as 01:06:40" do
      @timer.seconds = 4000
      @timer.time_string.should == "01:06:40"
    end
      end


  # One way to implement the Timer is with a helper method.
  # Uncomment these specs if you want to test-drive that
  # method, then call that method from inside of time_string.
  #

=begin
   describe 'padded' do
     it 'pads zero' do
       @timer.padded(0).should == '00'
     end
     it 'pads one' do
       @timer.padded(1).should == '01'
     end
     it "doesn't pad a two-digit number" do
       @timer.padded(12).should == '12'
     end
   end
=end
end

你的测试和 Timer 的问题在于,在你的测试中你设置了 @timer.seconds 的值,但是 Timer#time_string 不依赖于 @seconds 变量集。您的 time_string 方法的实现方式是接受 seconds 的数量作为参数,而不是 Timer.

的属性

尝试按如下方式更改您的测试:

describe "Timer" do
  # rest of your code

  describe 'time_string' do
    it "should display 0 seconds as 00:00:00" do
      @timer.time_string(0).should == "00:00:00"
    end

    it "should display 12 seconds as 00:00:12" do
      @timer.time_string(12).should == "00:00:12"
    end

    it "should display 66 seconds as 00:01:06" do
      @timer.time_string(66).should == "00:01:06"
    end

    it "should display 4000 seconds as 01:06:40" do
      @timer.time_string(4000).should == "01:06:40"
    end
  end
end

您可能想知道 好吧,但是为什么第一个测试 - 00:00:00 - 首先成功了?。好吧,这是因为您的 time_string 方法参数默认为 0:

def time_string(time=0)
  # Rest of the code
end

并且因为您没有传递任何其他值,所以使用了 0。

如果您有任何问题 - 我很乐意为您提供帮助!

祝你好运!

编辑

如果你想反过来 - 让 class 为你的测试工作,改变你的 Timer class:

class Timer
  def initialize
    @seconds = 0
  end

  def seconds
    @seconds
  end

  def seconds=(time)
    @seconds = time
  end

  def time_string
    #format of hour:minute:second
    #minute must be less than 59 (or 59*60 seconds), otherwise it will convert to hour
    minute = @seconds/60    #note that this is integer math, so it will take the minute and not the remainder
    hour = minute/60
    remainder_seconds = @seconds%60
    if @seconds<=9
      return "00:00:0" << @seconds.to_s
    elsif @seconds>9 && @seconds<=60
      return "00:00:" << @seconds.to_s
    elsif @seconds>60 && @seconds<=9*60 #9 minutes and greater than 1 min
      #ensuring double XX seconds or 0X seconds (this would be easier to use the padded method)
      if remainder_seconds >9
        remainder_seconds_sd = remainder_seconds.to_s
      else
        remainder_seconds_sd = "0" << remainder_seconds.to_s
      end

      return "00:0" << minute.to_s << ":" << remainder_seconds_sd
    end
  end
end

我们添加了 initialize 方法,我们更改了 def seconds=(time) 方法,并且我们更改了您的 time_string 方法中出现的所有 time

如果适合您,请考虑将代码发布到 https://codereview.stackexchange.com/。代码中有很多需要改进的地方,codereview 是寻求帮助的好地方!

更干净的版本:

class Timer
  attr_accessor :seconds

  def initialize
    @seconds = 0
  end

  def time_string
    seconds = @seconds % 60
    minutes = (@seconds / 60) % 60
    hours = @seconds / (60**2)
    "#{padded(hours)}:#{padded(minutes)}:#{padded(seconds)}"
  end

  def padded(num)
    return '0' + num.to_s if num < 10
    return num.to_s if num >= 10
  end
end