Cách tắt use_transactional_fixtures của rspec

Vấn đề

Trong dự án Ruby on Rails, khi viết spec , rất ít người để ý đến 1 thiết lập rất quan trọng của rspec là use_transactional_fixtures. Xem trong spec/rails_helper.rb ta sẽ thấy đoạn sau:

RSpec.configure do |config|
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = true
end

Mặc định rspec thiết lập user_transaction_fixtures là true. Như vậy thì tất cả các example của rspec sẽ được chạy trong 1 transaction. Khi example kết thúc, rspec tự động rollback database sẽ giúp cho database luôn ở trạng thái sạch sẽ nhất khi chạy example.

Nhưng sẽ có những trường hợp sử dụng transactional_fixtures có thể ảnh hưởng đến kết quả test. Trong những trường hợp như vậy cần vô hiệu hoá chức năng này.

Giải pháp

Cách đơn giản nhất là:

RSpec.configure do |config|
  # If you're not using ActiveRecord, or you'd prefer not to run each of your
  # examples within a transaction, remove the following line or assign false
  # instead of true.
  config.use_transactional_fixtures = false
end

Nhưng như thế dữ liệu đã tạo trong quá trình chạy example sẽ được lưu lại, có thể gây ảnh hưởng đến những example khác. Có một cách là sử dụng after để xoá thủ công những record đã tạo ra.

require 'rails_helper'

RSpec.describe Operator do
  after do
    Operator.delete_all
  end
end

Việc xoá thủ công như vậy tốn rất nhiều công sức nên đây không phải là giải pháp tốt nhất. Cách tốt nhất là chỉ vô hiệu hoá transactional_fixtures đối với example cần thiết.

require 'rails_helper'

RSpec.describe Operator do
  self.use_transactional_fixtures = false
end

Bên trên là ví dụ cách vô hiệu hoá transactional_fixtures đối với tất cả example của Operator.