datetime型を持つモデルのテスト

Ruby on Railsにおいて,テスト環境がとっても気持ちがいいと「前のエントリ」で書いたが,実際にテストケースを書き始めると,やっぱり知らないことがいろいろと出てきて,サクサクっとはいかない。もちろん,それは俺がバンビーノだからなのだが。。。

datetime型な列があるappointments表のAppointmentモデルをテストすることを考える。fixtureには,こんな感じで記述するだろう。

first: id: 1 promise: 2007-07-10 13:30:00

さて,Appointmentモデルのテストコードだが,

class AppointmentTest < Test::Unit::TestCase def setup @appointment = Appointment.find(1) end def test_create assert_kind_of Appointment, @appointment assert_equal 1, @appointment.id assert_equal ‘2007-07-10 13:30:00’, @appointment.promise end end

とすると,「ダメじゃないかなぁ」と記述中に思っていたのが的中し,Failureになってしまった。

1) Failure: test_create(AppointmentTest) [./test/unit/appointment_test.rb:13]: expected but was

.

ま,これは当然で,期待する値を文字列で,実際の値はTimeインスタンスで,っていう型違いで比較しているので,こういった問題が出てしまう。オオボケといえばそうなんだけど。

文字列として比較をする方向で修正を試みる。Timeクラスには,strftimeメソッドによって,指定した書式により日時を文字列化することができる。よって,ここではモデルから日時オブジェクトを取り出した後に,strftimeメソッドにfixtureで使用した書式を渡して文字列化し,その結果を比較するようにすればうまくいく。

class AppointmentTest < Test::Unit::TestCase def setup @appointment = Appointment.find(1) end def test_create assert_kind_of Appointment, @appointment assert_equal 1, @appointment.id assert_equal ‘2007-07-10 13:30:00’, @appointment.promise.strftime(“%Y-%m-%d %H:%M:%S”) end end

もう一つの方法として,Timeクラスのインスタンスに揃えて比較を行ってみる。Timeクラスのlocalメソッドに年月日時分秒の値をそれぞれ渡せばTimeインスタンスを得ることができるので,期待する値にこれを適用する。

class AppointmentTest < Test::Unit::TestCase def setup @appointment = Appointment.find(1) end def test_create assert_kind_of Appointment, @appointment assert_equal 1, @appointment.id assert_equal Time.local(2007, 7, 10, 13, 30, 0), @appointment.promise end end

どちらかの方法(個人的には後者が好み)をassert_datetimeなどという名前の共通メソッドとして作っておけば,便利メソッドとして重宝するかも。

このエントリーをはてなブックマークに追加

関連記事

スマートスピーカーはもう終わったデバイス?

QMK FirmwareとRaspberry Pi PicoでSPLIT_USB_DETECTを使わない方法

40%キーボードに慣れるためにやったこと

Lunakey PicoでQMK Firmwareを動かしてみました

Googleアシスタント向け会話型アクションが1年後にシャットダウンされます