计时器 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
我正在尝试解决 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