問題
- 7年前からのアプリケーション。フィクスチャとFactoryBotを使ったspecが混在している。フィクスチャを使ったspecを書き直すのは面倒。
- feature specをsystem specに変更し、DatabaseCleanerを使うのをやめ、use_transactional_fixturesをtrueに変更した。
- フィクスチャデータがテストDBに残って、FactoryBotを使ったspecに影響を与えるので困る。
フィクスチャとRspecのHooks
「use_transactional_fixtures = true」では、次のような流れになります。投入されたフィクスチャデータは消されません。フィクスチャデータが一度投入されると、テーブル名がキャッシュに保存され、次に「fixtures テーブル名」が来たら投入はスキップ、となります。
before(:context)
DELETE FROM フィクスチャのテーブル
INSERT INTO フィクスチャのテーブル
BEGIN
before(:example)
テストコード実行
after(:example)
ROLLBACK
BEGIN
before(:example)
テストコード実行
after(:example)
ROLLBACK
after(:context)
対策
after(:context)でレコードを消し、フィクスチャのキャッシュも消す。
config.after(:context) do |example|
fixtures = ActiveRecord::FixtureSet.cached_fixtures(ActiveRecord::Base.connection)
fixtures.collect(&:model_class).each(&:delete_all)
ActiveRecord::FixtureSet.reset_cache
end
上記の変数fixturesは、ActiveRecord::FixtureSetのインスタンスの配列です。Railsのソースはこちら。
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/fixtures.rb