(2008/09/12修正)
railsでテストをするときに、fixtureの定義をしなくてはならないことが多々あります。
テーブルが少ないときは手で一つずつ書いていってもいいのですが、テーブルが多いととても大変です。そこで簡単にfixtureを作る方法はないものか調べてみました。
上記の記事に書いてあるように、RAILS_ENVのDBデータをfixtureに変換してあげると楽にfixtureが作れそうです。*1。
記事の通りpluginをインストールしてみようかなと思ったら、pluginはgemに統合されたみたいです。まずはインストール。
sudo gem install ar_fixtures
これですぐ使える!と思いきやそうでもないみたい。ドキュメントもしっかり書かれていないっぽいので類推しつつ使えるようにしてゆきました。まずrakeファイルがあるのでコピー
cp /Library/Ruby/Gems/1.8/gems/ar_fixtures-0.0.4/tasks/ar_fixtures.rake RAILS_ROOT/lib/tasks
次にar_fixtures.rakeを編集します。
emacs RAILS_ROOT/lib/tasks/ar_fixtures.rake
一行目、二行目に下記を追加。これでひとまず動くようになります。
require "ActiveRecord" require "ar_fixtures"
使い方はこんなふうにします。
rake db:fixtures:dump MODEL=modelname
でもこれだと複数のテーブルをfixtureに変換することができません。そこで、ar_fixtures.rakeを下記のように編集しました。
require "ActiveRecord" require "ar_fixtures" def env_or_raise(var_name, human_name) if ENV[var_name].blank? raise "No #{var_name} value given. Set #{var_name}=#{human_name}" else return ENV[var_name] end end def model_or_raise return env_or_raise('MODEL', 'ModelName') end def limit_or_nil_string ENV['LIMIT'].blank? ? 'nil' : ENV['LIMIT'] end namespace :db do namespace :fixtures do desc "Dump data to the test/fixtures/ directory. Use MODEL=ModelName and LIMIT (optional)" task :dump => :environment do eval "#{model_or_raise}.to_fixture(#{limit_or_nil_string})" end namespace :dump do desc "Dump all data to the test/fixtures/ directory. " task :all => :environment do Dir["app/models/*.rb"].each{|i| eval File.basename(i, '.rb').classify} Object.subclasses_of(ActiveRecord::Base).each{|klass| klass.to_fixture rescue p klass.name} end end end namespace :data do desc "Dump data to the db/ directory. Use MODEL=ModelName and LIMIT (optional)" task :dump => :environment do eval "#{model_or_raise}.dump_to_file(nil, #{limit_or_nil_string})" puts "#{model_or_raise} has been dumped to the db folder." end desc "Load data from the db/ directory. Use MODEL=ModelName" task :load => :environment do eval "#{model_or_raise}.load_from_file" end end end
これで下記のようにすると全てのテーブルがtest/fixtures配下にyamlとして保存されます。
rake db:fixtures:dump:all
rspec使いの人はar_fixtures/lib/ar_fixtures-0.0.4.rbをs/test\/fixtures/spec\/fixtures/gすればOKです。
これで少しテストが楽になりました。でも、もっとうまい方法がありそう。心当たりのある方は教えていただけると嬉しいです。
*1:でもこれが有効に使えるためには登録系のロジックが全部出来上がっている必要がありますね。