woshidan's blog

そんなことよりコードにダイブ。

Railsで当日の日付を使った関数のテストをする

今週テストを書いていて、地味に引っかかっていた……。

Rails 4.1 + Minitestのテストでシステムの日付を気にする関数のテストがしたかったのです。

Date.todayの日付を固定したい

[Ruby on Rails]Date.todayとかを使っている箇所をテストする方法 | GENDOSU@NET

timecopというgem

travisjeffery/timecop · GitHub

を追加して、

Date.today
=> Sun, 15 Jun 2014
Timecop.travel(Date.new(2011,11,11))
# Date.new(2011,11,11)は設定したい日付

とすると、

Date.today
=> Fri, 11 Nov 2011

となって、

ActiveRecordの保存時間も

User.create
INSERT INTO `users` (`created_at`, `updated_at`) VALUES ('2011-11-11 00:00:15', '2011-11-11 00:00:15')

となる。

日付を固定する処理が終わった後は、

Timecop.return

で元の日付に戻すこと。

 

DateやTimeの.stubメソッドを使う 

書いている間は何となくgemを入れていいのかひよっていたし、

時間を固定したい処理をDate.stubのブロックの中に入れる方法もある。

Date.stub :today, Date.parse("2011-11-11") do
      Time.stub :now, Time.parse("11:11") do
        @user = User.create
      end
  end

 

ただ、これをこんな感じでMinitestのテストで使おうとしたら

def setup
    Date.stub :today, Date.parse("2011-11-11") do
      Time.stub :now, Time.parse("11:11") do
        @user = User.create
      end
    end
end

test "Date.stub time" do
  assert_equal "2011-11-11", @user.created_at.to_s
end
1) Failure:
TimeStubTest#test_Date.stub_time [/Users/woshidan/sample/test/time_stub_test.rb:12]:
Expected: "2011-11-11"
  Actual: "2014-06-15 02:11:00 UTC"

となって、失敗した……orz

もしかして、データベースへの保存時間はDate.stub設定では変わらないかしら。

ActiveRecordさんはどこから日付を取っていらっしゃるのか。

(日付のあとがなくて失敗するなら想定通りなのだけれど)

 

そうだ、ためしに無理矢理書いてみよう

あれこれ思いながら、かなり無理矢理めなのだけど、

def setup
  @user = User.create(:created_at => "2011-11-11")
end

と書いてみたら、

Expected: "2011-11-11"
  Actual: "2011-11-11 00:00:00 UTC"

となって、ますます意味が分からなくなってます。

 

え、あなた直接書けたの……書けてよかったの……?

という感じ。