Rspecでuse_transactional_fixturesはexampleのみにtransactionを張る

Rspecの基本的なことを知らなかったのでメモ。

rails_helper.rb

RSpec.configure do |config|
  config.use_transactional_fixtures = true
end

1つ1つのテストにtransactionを張って、テスト終了時に必ずrollbackしてくれる設定。

user_spec.rb

require 'rails_helper'

RSpec.describe User, type: :model do

  # 普通にexample内に書かれてたらrollbackされる
  example 'create a user in an example' do
    ichiro = FactoryBot.create(:user, first_name: 'ichiro')
    expect(ichiro.first_name).to eq 'ichiro'
  end

  # beforeブロック内もexampleに入ってから評価されるのでrollbackされる
  describe 'create a user in a before block' do
    before { FactoryBot.create(:user, first_name: 'jiro') }
    it { expect(User.last.first_name).to eq 'jiro' }
  end

  # letブロック内もexampleに入ってから評価されるのでrollbackされる
  describe 'create a user in a let block' do
    let(:saburo) { FactoryBot.create(:user, first_name: 'saburo') }
    it { expect(saburo.first_name).to eq 'saburo' }
  end

  # let!ブロック内もよくわからんがtransactionの内側らしい
  describe 'create a user in a let block' do
    let!(:shiro) { FactoryBot.create(:user, first_name: 'shiro') }
    it { expect(shiro.first_name).to eq 'shiro' }
  end

  # describeに直接書くとexample内ではないのでtransactionは張られておらず、rollbackされない。
  FactoryBot.create(:user, first_name: 'goro')
end

user_spec.rb実行前のtestDB

mysql> select first_name from users;
Empty set (0.00 sec)

user_spec.rb実行後のtestDB

mysql> select first_name from users;
+------------+
| first_name |
+------------+
| goro       |
+------------+
1 row in set (0.00 sec)