■概要
(激しく既出感ありですが。。)何年もrailsやってますが、正しく理解できていなかった事の一つに
rake spec(test)すると、処理の一環としてdb:test:prepareタスクを呼び出す
という挙動があります。
通常問題にならないのですが、db:test:prepareが、db/schema.rbの情報を元にデーターベースを作成する為、railsが認識できないような項目は抜けて落ちてしまいます。
- 関数適用したインデックス
- トリガーやファンクション
- 別スキーマに作ったオブジェクト ...etc
なので
RAILS_ENV=test rake db:drop
RAILS_ENV=test rake db:create
RAILS_ENV=test rake db:migrate
してからrake specする事を前提に、db:test:prepareを呼び出さずにspecを実行する方法を模索しました。
■案1 db:test:prepare自体を書き換える
参照先にそのまんまの解決策が書かれています。
Rakefileでtask削除用のメソッドを用意します(load_tasksの前に!)。
Rake::TaskManager.class_eval do def remove_task(task_name) @tasks.delete(task_name.to_s) end end
lib/tasks/db/test.rakeとかを作って、実際にタスクを上書きします
Rake.application.remove_task 'db:test:prepare' namespace :db do namespace :test do task :prepare do |t| # rewrite the task to not do anything you don't want end end end
参考 http://stackoverflow.com/questions/1097845/how-to-prevent-rake-test-to-call-task-dbtestprepare
■案2 自力でspecを実行する
db:test:prepareを壊すのは怖いので...という方にはこのやり方
lib/tasks/spec.rakeとかを作って
require 'rake' require 'rspec/core/rake_task' namespace :spec do RSpec::Core::RakeTask.new('no_prepare_db') do |t| t.pattern = ['spec/**/*_spec.rb'] end namespace :no_prepare_db do %w(controllers helpers lib mailers models requests routing views).each do |dir| RSpec::Core::RakeTask.new(dir) do |t| t.pattern = ["spec/#{dir}/**/*_spec.rb"] end end end endで、rake spec:no_prepre_dbや、rake spec:no_prepare_db:modelsで、db:test:prepareを呼び出さずに実行できます。
参考 http://old.nabble.com/db%3Atest%3Aprepare-interfering-with-rake-spec-pattern-td31075510.html
0 件のコメント:
コメントを投稿