Edited at

【Rails】factory_botの使い方メモ


さいしょに

railsのテストでmodelを扱うのに便利なFactoryBotのメモ。

最初に設定をしておくと user = create(:user) みたいな形でDB登録やモデルのビルドができる。

この記事はrails newできたからとりあえずテスト自動化してみた(selenium/rspec/capybara) - QiitaでRSpecやCapybaraの設定が完了している前提で記載してます。


インストール


Gemfile

group :test do

gem 'factory_bot_rails'
gem 'database_cleaner'
end

database_cleanerはFactoryBotでDB登録したデータをテスト終了後にクリアするために使う。

$ bundle install


DatabaseCleanerの設定


spec/rails_helper.rb

...

RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods

config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end

config.before(:each) do
DatabaseCleaner.start
end

config.after(:each) do
DatabaseCleaner.clean
end

config.before(:all) do
DatabaseCleaner.start
end

config.after(:all) do
DatabaseCleaner.clean
end
end


before(:each)before(:all)のどちらでDB登録されてもafter処理でtruncateされるように設定しておきます。


FactoryBotの準備

FactoryBotのデータはspec/factories/xxxxx.rbに設定しておく。

以下、name属性を持つUserモデルを前提。


モデル名そのままの場合


spec/factories/user.rb

FactoryBot.define do

factory :user do
name { "testuser1" }
end
end


モデル名以外の名前をつける場合


spec/factories/user.rb

FactoryBot.define do

factory :testuser, class: User do
name { "testuser2" }
end
end

factoryの後方のclassでモデルを指定すればモデル名以外を定義しておくこともできる。

利用用途によってわかりやすい名称にしておくとテストが捗るかも。


FactoryBotを使用する

FactoryBotはspecファイル内で使う。

基本的にはbefore(:each)内で定義してあげるのがよさげ。


spec/features/xxxxx_spec.rb

require "rails_helper"

feature "xxxxx" do
before(:each) do
@user = create(:user) #ここで定義
end

scenario "xxxxx" do
xxxxx
end
end


定義の仕方は以下の通り。よく使うもののみなので詳しくは factory_bot を参照。


DB登録する

@user = create(:user)

DBにname = testuser1のUserが登録され、かつ、@userにそれが代入されている状態になる。


DB登録しない(ビルドまで)

@user = build(:testuser)

DB登録はされず、@username = testuserのモデルが代入されている状態になる。


属性を上書きしてDB登録する

@user = create(:user, name: "username")

name = usernameのモデルがDB登録される。@userにもそれが代入される。

associationがある場合などに、@blog = create(:blog, user_id: @user.id)みたいな感じで使ってます。


さいごに

テストのたびにテストデータを用意する必要がないのでとても便利です。


Reference