背景
業務でRailsではないRubyプログラムの改修を行うことになりました。
既存のテストを実行してみると、Rspec実行後にDBの値が書き換えられていて2度目のテスト実行でDB側で重複エラーになってしまいました。
デバッグを進めていくとDatabaseCleanerが正常に動作せず、トランザクションが張られていないことが原因のようでした。
そこからググりまくって色々試してみたのですが(バージョンが古く、use_transactional_fixturesの設定もできない)うまくいきませんでした。
そこで、暫定対処としてRspecからDBをCreateした場合、Rspecのexampleごとに削除する処理をサクッと入れることにしました。(トランザクションは使用しない)
とりあえずDatabaseCleaner入れるのめんどくさいという人や、環境が原因でうまくDatabaseCleanerが動いてくれない人等に暫定対処としてサクッと書ける処理を共有できればと思います。
暫定対処法
処理フロー
beforeで配列を作成してその中にCreateしたオブジェクトを追加していきます。
afterで配列をループさせdeleteを行います。
before :each do
# FactoryGirlでクリエイトしたオブジェクトを配列に入れておく
@data_obj = Array.new
@data_obj << create(:factory)
@data_obj << create(:factory)
end
after do
# オブジェクトに対してdeleteメソッドを実行
@data_obj.each do | delete_obj |
delete_obj.delete
end
end
超絶簡単ですが、これでDatabaseCleanerを使えるように環境を再構築したり、環境のバージョン差分を解消するまでの間の暫定対処としてうまく動作させられるようになると思います。
まとめ
-
Railsを使用しない場合の情報がかなり乏しい。
-
自分で構築した環境ではないので原因を特定しにくい。
-
レガシーな構成なものを改修する時、不具合が起きやすい。
-
構成を好き勝手にいじることができない場合(根本的な解決ができない)、自分で処理を書くことでお茶を濁すしかない。
誰かが困ったときの一時的な助けとならんことを祈ります。