获取当前时间的单元测试代码

Gre*_*Dan 5 ruby datetime unit-testing ruby-on-rails

为当前时间的代码编写单元测试的最佳方法是什么?例如,某些对象可能仅在工作日创建,其他对象在检查执行某些操作的权限时会考虑当前时间等.

我想我应该嘲笑Date.today和Time.now.这是正确的方法吗?

更新:两种解决方案(a)Time.is和(b)Time.stubs(:now).returns(t)工作.(a)是非常好的方法,但(b)解决方案将与其他测试代码更加一致.

在这个问题上,作者要求提供一般解决方案.对于Ruby,在我的选项中,上述两个解决方案更简单,因此比提取获取当前日期/时间的代码更好.

顺便说一句,我建议使用慢性来获得所需的时间,例如

require 'Chronic'    
mon = Chronic.parse("next week monday")
Time.stubs(:now).returns(mon)
Run Code Online (Sandbox Code Playgroud)

Aar*_*nni 6

以下是Jay Field的思想.它允许您重新定义Time.now块的持续时间.

require 'time'

class Time
  def self.metaclass
    class << self; self; end
  end

  def self.is(point_in_time)
    new_time = case point_in_time
      when String then Time.parse(point_in_time)
      when Time then point_in_time
      else raise ArgumentError.new("argument should be a string or time instance")
    end
    class << self
      alias old_now now
    end
    metaclass.class_eval do
      define_method :now do
        new_time
      end
    end
    yield
    class << self
      alias now old_now
      undef old_now
    end
  end
end

Time.is(Time.now) do
  Time.now # => Tue Nov 13 19:31:46 -0500 2007
  sleep 2
  Time.now # => Tue Nov 13 19:31:46 -0500 2007
end

Time.is("10/05/2006") do
  Time.now # => Thu Oct 05 00:00:00 -0400 2006
  sleep 2
  Time.now # => Thu Oct 05 00:00:00 -0400 2006
end
Run Code Online (Sandbox Code Playgroud)


dst*_*rkr 3

模拟 Time.now 或 Date.today 似乎很简单,看起来像:

require 'rubygems'
require 'test/unit'
require 'mocha'

class MyClass

  def foo
    Time.now
  end

end

class MyTest < Test::Unit::TestCase

  def test_foo
    assert true
    t = Time.now
    Time.expects(:now).returns(t)
    assert_equal t, MyClass.new.foo
  end

end
Run Code Online (Sandbox Code Playgroud)