3 日坊主日記
2006-11-28 [長年日記]
_ [第五] 本日のリンク元が寂しくなってる
けどなんでなのか分からない。
追記: 以前の日記へのリンク元 に出るということか。 でも本日のリンク元にupdate.rbが出るのはなんでだろう。
追記: plugin.defaultのほうをupしてなかった。これでどうかな。
_ 聖剣1
久しぶりにGB電源入れたらまだ動いた。コンティニューしたらどこなのか分からない(かなり始めのほうぽい)。音楽にほのぼの。
_ [Rails] Time.nowの固定
以前るびまで書いたように、時刻を扱うテストではテストデータを動的に変えるかTime.nowを固定する。 ここではTime.nowを固定する方法だけを見る。
参考になるのはActiveRecordのテストに出てくる方法。
# activerecord/test/mixin_test.rb:
# Let us control what Time.now returns for the TouchTest suite
class Time
@@forced_now_time = nil
cattr_accessor :forced_now_time
class << self
def now_with_forcing
if @@forced_now_time
@@forced_now_time
else
now_without_forcing
end
end
alias_method_chain :now, :forcing
end
end
class TouchTest < Test::Unit::TestCase
fixtures :mixins
def setup
Time.forced_now_time = Time.now
end
def teardown
Time.forced_now_time = nil
end
def test_time_mocking
five_minutes_ago = 5.minutes.ago
Time.forced_now_time = five_minutes_ago
assert_equal five_minutes_ago, Time.now
Time.forced_now_time = nil
assert_not_equal five_minutes_ago, Time.now
end
#...
end
自分のテストでもこれを使えばok。
さて、このTime.nowを固定する方法は、実際にウェブサーバ上で動してみるときにも使いたいことがある。 例えば日付ごとに内容が変わるページがあるとして、動作確認のためだけに日付パラメータを渡すように実装するのは面倒くさいし、その日の分だけ出力するなら要らないはずの、過去未来に対するアクセス制限とか余計なことに時間がかかる。
単純に先のTimeクラス定義をconfig/environment.rbに置き、 適当なアクションを用意すれば
require 'time'
def forced_time
Time.forced_now_time = params[:time] ? Time.parse(params[:time]) : nil
redirect_to :action => 'index'
end
アプリでTime.now固定が使えるわけだけど、 実際にはこれだと影響が大きすぎる。 例えば、ログのタイムスタンプも動いてしまう。
なので、別のクラスTimelineを用意しよう。
# app/models/timeline.rb:
class Timeline
@@forced_now_time = nil
cattr_accessor :forced_now_time
def self.now
@@forced_now_time || Time.now
end
end
def forced_time
Timeline.forced_now_time = params[:time] ? Time.parse(params[:time]) : nil
self.class.logger.info("Timeline.now: #{Timeline.now}")
redirect_to :action => 'index'
end
しかし、クラス変数はセッションを跨いで保持されないので (少なくともmongrelでは) これはうまくいかない。
なので、@@forced_now_timeをDBに格納する。Settings pluginを使う。
class Timeline
def self.now
forced_now_time || Time.now
end
def self.forced_now_time
Settings.forced_now_time
end
def self.forced_now_time=(time)
Settings.forced_now_time = time
end
end
[ツッコミを入れる]
[]