[ruby][rails]テストの時にTime.nowで好きな時間を使えるようにするMock

class AgentTest < Test::Unit::TestCase
  def test_notice
    Time.class_eval do
      class << self
        alias_method :real_now, :now
      end

      def self.mock_now
        @current_time
      end

      def self.mock!(time)
        class << Time; alias_method :now, :mock_now; end
        @current_time = time
        yield
        class << Time; alias_method :now, :real_now; end
      end
    end

    Time.mock!(Time.parse("2007-10-10 11:11:11")) do
      assert_equal "2007-10-10", Agent.notice[:date].strftime("%Y-%m-%d")
    end
  end
end

こんな感じ。特異クラスとか使うとかなりトリッキーなことができるとわかった。