我有一个这样的课。
class Time
def has_same_hours?(t)
self.strftime("%Y%m%d%H") == t.strftime("%Y%m%d%H")
end
end
class MyLogger
DATA_DIR = 'data'
def initialize
@time_current_hour = Time.now
@io = nil
update_io_to_current_hour
end
def update_io_to_current_hour
@io = open output_filename, "a+" if @io.nil?
return if @time_current_hour.has_same_hours? Time.now
@io.close
@io = open output_filename, "a+"
@time_current_hour = Time.now
end
def output_filename(time = Time.now)
"#{DATA_DIR}/#{time.strftime('%Y_%m_%d_%H')}.txt"
end
end
调用update_io_to_current_hour
时,如果小时与@time_current_hour
不同,则应更改文件IO。
我想为它编写RSpec测试。这就是我写的。
describe Logger do
let(:logger){ Logger.new }
describe "#update_io_to_current_hour" do
context "when the hour changes" do
before{
@time_now = Time.parse("2010/4/10 19:00")
@time_current = Time.parse("2010/4/10 18:59")
Time.stub(:now).and_return(@time_now)
logger.stub(:time_current_hour).and_return(@time_current)
}
it "should change file io" do
expect{logger.update_io_to_current_hour}.to change{ logger.instance_variable_get :@io }
end
end
context "when the hour doesn't changes" do
before{
@time_now = Time.parse("2010/4/10 18:59")
@time_current = Time.parse("2010/4/10 18:58")
Time.stub(:now).and_return(@time_now)
logger.stub(:time_current_hour).and_return(@time_current)
}
it "should not change file io" do
expect{logger.update_io_to_current_hour}.not_to change{ logger.instance_variable_get :@io }
end
end
end
end
第二次测试通过,首先没有。看起来文件io永远不会更改为Time
对象的存根。
我做错了什么?如何正确编写测试?
答案 0 :(得分:1)
有几点:
logger.stub(:time_current_hour)
该类没有名为:time_current_hour
的方法,只有一个实例变量。很少有理由测试实例变量的值;这是一个实现细节。你想测试行为。无论如何,这个存根是无效的。还
logger.instance_variable_get :@io
现在,您正在直接进入对象的内脏并检查其内部值。你不关心它的隐私吗? :)
如果您只是测试:output_filename
的值,我认为这会容易得多。当小时改变时,文件名会改变。当小时相同时,文件名是相同的。