1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rspec】時刻に関するテスト

Posted at

はじめに

あるユーザーのログイン履歴一覧を取得するAPIを作成した際のテストにて、時刻の扱い方で躓いたため整理しておきます。

前提

ユーザー(accounts)テーブルと、そのログイン履歴(logins)テーブルがある時。

やりたいこと

以下のようなデータを作成。

let(:login1_created_at) { 4.day.ago }

let!(:login1) { create(:login, account: account, created_at: login1_created_at) }

この状態でsubjectを走らせ、created_atの値が一致することをテストしたい。

困ったこと

responseで返ってきたaccountのcreated_atと、let!で作成したaccountのcreated_atが一致しない。

原因

これはRubyのTimeオブジェクトの仕様でcreated_atにて作成したデータはミリ秒まで含んでしまうためです。

ちなみに以下のコードで検証すると、それぞれ以下のような値が返ってきます。

subject
res = JSON.parse(response.body)
expect(Time.zone.parse(res["data"].to_s)).to eq login1.created_at.to_time
  • response
    Sun, 01 Aug 2021 14:58:19.000000000 JST +09:00

  • let1!
    2021-07-30 14:58:19.384332 +0900

let1!で作成したデータはミリ秒以下の細かい数字が出てしまい一致しませんでした。

解決

結論、ミリ秒以下の正確な値の検証は必要ないため、以下のようにto_sとしてミリ秒以下を切り捨てることで解決しました!

let!(:login1) { create(:login, account: account, created_at: login1_created_at.to_s) }
# 結果
2021-07-30 14:58 +0900

まとめ

時刻に関するテストでは正確に一致するのを確認するのは難しいため、以下のようなメソッドを使う方法も検討すると良いかもしれません。

  • be_within

    • 指定した秒数は切り捨てられる
  • travel_to

    • it の下に定義することで任意の時間を指定して、テストを走らせることができる。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?