テストコードからのフィクスチャの参照

■フィクスチャをロードすると、そのデータはテストケースから参照できる。その時の注意点
※参考 「Railsによるアジャイル〜」p.151



【1.参照の仕方】
テストケースからフィクスチャデータを参照する方法は3つある。(この例では、:productsフィクスチャ)
をロードしたとする。また、その内容は以下の通り。


                                                            • -

products.yml

version_control:
id: 1
title: 2
date_time: 2005-01-26 00:00:00

                                                            • -

▼参照方法
 A.@productsインスタンス変数を使う
  例: vc = @products["version_control"]
     assert_equal vc["id"], @product.id
※@products[:version_control]と、シンボルを使った書き方はできない



 B.アクセサメソッドproductsを用いる
  例: vc = products(:version_control)
※この書き方だと、シンボルでも文字列で指定してもOK



 C.名前付フィクスチャと同名のインスタンス変数を用いる
  例: vc = @version_control



【2.これらを使う際の注意】
実は、A〜Cには違いがある。それは、何を参照するかであり、これの使い方を間違えると、テストが
失敗してしまうことがある。次の例を見る。



 def test_create
  vc = @products["version_control"]
  assert_equal vc["date_time"] , @product.date_time
 end



結論から言うと、これはfailureする。フィクスチャの構成を見ると分かるが、date_timeは、DB内では
datetime型。よって、DBからロードされる際に、Rubyの対応する型である、Date型にキャストされ
ます。よって、まず、@product.date_timeはTime型なのです。
一方、vc["date_time"]は、 "2005-01-26 00:00:00"という文字列を持ってくるのです。よって、内容
は一致するのですが、型の不一致でテスト失敗となります。



さて、何故このようなことが起こるかというと、それは@products["version_control"]は、フィクスチャの
生データそのものを参照するからです。よって、フィクスチャファイルの、date_timeの所に書いてある、
"2005-01-26 00:00:00"を参照してしまうのです。
これを解決する方法が主に3つあります。



1._type_before_castを用いる
 @product.date_time_type_berfore_castとすると、date_timeの生の値を取得してくれ、型は
 考慮されなくなります。そこで取得されるデータは"2005-01-26 00:00:00"なので、assert成功。



2.共に、.to_sを付ける
 ある意味邪道です。



3.BまたはCの参照方法を用いる
 実は、ここに、A〜Cの違いがあるのです。正確には、B,Cは参照する先という意味では同じです。
 B,Cの方法だと、フィクスチャデータが、DBにロードされ、それをフィクスチャの指定によってロード
 した値を参照します。
 よって、@productのように、直接フィクスチャファイルのデータを見るのではなく、一回DBに入ったものを
 ロードするのです。よって、その際に型変換が行われ、以下のテストは成功します。


 
 def test_create
  vc = products("version_control")
  assert_equal vc["date_time"] , @product.date_time
 end