さいしょに
railsのテストでmodelを扱うのに便利なFactoryBotのメモ。
最初に設定をしておくと user = create(:user)
みたいな形でDB登録やモデルのビルドができる。
※RSpecのSystemテストをする場合、テストで利用したデータは自動で削除されるようになったのでdatabase_cleaner
は不要です。
インストール
group :test do
gem 'factory_bot_rails'
gem 'database_cleaner'
end
database_cleaner
はFactoryBotでDB登録したデータをテスト終了後にクリアするために使う。
$ bundle install
DatabaseCleanerの設定
...
RSpec.configure do |config|
# FactoryBotの利用をON
config.include FactoryBot::Syntax::Methods
# DatabaseCleanerの設定
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
モデルを前提。
モデル名そのままの場合
FactoryBot.define do
factory :user do
name { "testuser1" }
end
end
モデル名以外の名前をつける場合
FactoryBot.define do
factory :testuser, class: User do
name { "testuser2" }
end
end
factory
の後方のclass
でモデルを指定すればモデル名以外を定義しておくこともできる。
利用用途によってわかりやすい名称にしておくとテストが捗るかも。
FactoryBotを使用する
FactoryBotはspecファイル内で使う。
基本的にはbefore(:each)
内で定義してあげるのがよさげ。
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登録はされず、@user
にname = testuser
のモデルが代入されている状態になる。
属性を上書きしてDB登録する
@user = create(:user, name: "username")
name = username
のモデルがDB登録される。@user
にもそれが代入される。
associationがある場合などに、@blog = create(:blog, user_id: @user.id)
みたいな感じで使ってます。
さいごに
テストのたびにテストデータを用意する必要がないのでとても便利です。