Help us understand the problem. What is going on with this article?

DatabaseRewinderでseedなど消さないで欲しいデータがいる場合の対処方法

More than 3 years have passed since last update.
  • seedで入れたデータがtest DBのテーブルに入っている
  • どういうわけか、ユーザーがそのテーブルに追加する箇所があり、そのテストを書きたい

DatabaseRewinderの動きをおさらい

DatabaseRewinderは、そのテストが走っている時に実行された 1. INSERT文を監視して対象テーブルを記憶 して、 2. DatabaseRewinder.clearしたときにその対象テーブルに対してDELETE文を発行する

問題が起きるシーン

テストの中で、seedで入れたデータが存在するテーブルにデータを追加する場合、 INSERT文が発行される ので、DatabaseRewinderの削除対象となってしまい、seedで入れたデータが失われる。

解決方法

DatabaseRewinderが以下のように設定されているという前提

spec/rails_helper.rb
RSpec.configure do |config|
  config.before(:all) do
    DatabaseRewinder.clean_all
  end

  config.before(:each) do
    DatabaseRewinder.clean
  end
end

テストの中で、以下の様な after 処理を用意しておく。

hogehoge_spec.rb
  after :each do
    # このtest内でpiyopiyo_categoryを増やすがDatabaserewinderの対象としない
    DatabaseRewinder.cleaners.each do |cleaner|
      cleaner.inserted_tables.reject!{|table| table.match /piyopiyo_categories/}
    end
    # 増やした分 = user_id: 0以外を消す
    PiyoPiyoCategory.where.not(user_id: 0).delete_all
  end

根本解決

  • seedもfactoryですべて用意する
  • before :eachで流せるレベルのコンパクトなテスト用seedを用意する
  • 設計の段階でマスターデータの存在するテーブルとユーザーが追加しうるデータを混在させない
ppworks
最近は主にrailsです!
http://ppworks.jp
esaLLC
esa.io や pplog.net などのWebサービスを開発・デザイン・運営しています
https://team.esa.io
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away