如何使用RSpec测试文件IO是否根据时间更改

时间:2014-04-10 09:45:13

标签: ruby rspec

我有一个这样的课。

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对象的存根。

我做错了什么?如何正确编写测试?

1 个答案:

答案 0 :(得分:1)

有几点:

logger.stub(:time_current_hour)

该类没有名为:time_current_hour的方法,只有一个实例变量。很少有理由测试实例变量的值;这是一个实现细节。你想测试行为。无论如何,这个存根是无效的。还

logger.instance_variable_get :@io

现在,您正在直接进入对象的内脏并检查其内部值。你不关心它的隐私吗? :)

如果您只是测试:output_filename的值,我认为这会容易得多。当小时改变时,文件名会改变。当小时相同时,文件名是相同的。