Railsの fixturesはたいへん便利な仕組みなのだが、今までは決められた名前のディレクトリ($RAILS_ROOT/test/fixtures/)内の決められた名前(テーブル名と同じ名前)のファイルしか読み込めないという制約があったため、例えば複数パターンのテストデータを用意しおいて切り替えて DBに食わせたいような場合なんかに、ちょっと不便に感じることがあった。
が、最近の edgeでは2箇所ほど fixtures関連の修正が入っており、fixturesの使い勝手が向上している。
 

1. サブディレクトリ内の fixturesを読み込む rakeタスク

まず、fixturesをディレクトリで分けて複数用意してディレクトリ名を指定して読み込む rakeタスクが 実装された

例えばこんな fixturesファイルを用意して、

test/fixtures/users.yml

john:
  name: John

paul:
  name: Paul

ふつうに rakeタスクで loadすると、

$ rake db:fixtures:load

DBの中身はこうなる。

$ ./script/runner 'p User.all.map(&:name)'
["Paul", "John"]

 
と、ここまでは従来どおりだが、さらに Rails 2.2では、こんなディレクトリを用意して、

$ mkdir test/fixtures/ja

こんな fixturesファイルを作ったら、

test/fixtures/ja/users.yml

taro:
  name: 太郎

hanako:
  name: 花子

こんなコマンドで loadできるようになった。

$ rake db:fixtures:load FIXTURES_DIR=ja

結果はこのとおり。

$ ./script/runner 'p User.all.map(&:name)'
["花子", "太郎"]

 

2. fixturesメソッドでテーブル名と同じ名前以外の任意のファイルを読み込めるようになった

こちらの件は、折しも RubyKaigi 2008の会場で Rails勉強会@東京ブースのよろず質問コーナーで質問を頂いた内容だったりする。
Rails 2.2では このパッチのコミットのおかげで バッチリ解決できそうになったので、いまさらここで遅レスな回答を。

例えば今度はこんな fixturesファイルを読み込ませたい場合、

test/fixtures/elp.yml

keith:
  name: Keith

greg:
  name: Greg

carl:
  name: Carl

テストケースではこんなふうに書けばOKになった。

test/unit/user_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  set_fixture_class :elp => User
  fixtures :elp
  
  test 'ELP should be loaded through YAML file' do
    assert_equal %w[Carl Greg Keith], User.all.map(&:name).sort
  end
end

しかし、今の Railsのデフォルトでは test/test_helper.rb に

fixtures :all

とか書いてあったりするので、fixturesディレクトリ直下にこんなファイルが置いてあると、全てのテストケースでこの ymlファイルを同名のテーブルにロードしに行こうとしてガンガン落ちる。

そこで、上記の1番の例を思い出して、特定のテストケースでのみ使いたいようなテストデータはサブディレクトリに置いとけば良いじゃん、というのがトレンドになりそう。

$ mkdir test/fixtures/users
$ mv test/fixtures/elp.yml test/fixtures/users/

テストはこんなふうに書けば、

test/unit/user_test.rb

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  set_fixture_class :'users/elp' => User
  fixtures :'users/elp'

  test 'ELP should be loaded through YAML file' do
    assert_equal %w[Carl Greg Keith], User.all.map(&:name).sort
  end
end
$ rake test:units
(中略)
1 tests, 1 assertions, 0 failures, 0 errors

カンペキ!
ポイントは、ディレクトリ名とファイル名をつなげたものを引用符で囲って書くところでしょうか。

以上、こんな感じで回答になってますでしょうか? > 川端さん

1 Response to “任意のファイル名とディレクトリ名の fixturesが読み込めるようになった”

  1. 川端 - July 25th, 2008 at 08:51 AM

    おお~、松田さんありがとうございます!!
    UserAクラスが、通常のDBを見に行って、UserBクラスが、magic_multi_connectionsを利用すれば、複数DBでFixtureを使い分けられそうですね。
    早速試してみたいと思います!これでEdgeに上げる理由が出来ました(笑)

Sorry, comments are closed for this article.