はじめに
前回RSpecによるテストコードの概要とRSpecの導入をアウトプットしました。
今回はどうせなので、RSpec導入したらほぼ確実にこれも使うでしょっていうFactoryBotの導入の仕方と説明をまとめてみました。よろしくお願いします。
また、例としてUserモデルの単体テストコードを書いていくことを想定して説明していきたいと思います。
FactoryBotの導入
テストコードでは、例えばUserモデルのテストコードを書く際に、まず適当に名前やE-mailアドレス、パスワードなどの情報を入力してあげないといけません。
user = User.new(nickname: 'aaaaa', email: 'test@example.com', password: '000000', password_confirmation: '000000')と言った具合に。
しかしこのような記述を毎回毎回記述するのは面倒なので、繰り返し同じような記述するのはまとめてしまった方が効率的ですね。そこで活躍するのがFactoryBotさんです!
FactoryBotは他のファイルにあらかじめ各クラスのインスタンスに上記のような定める値を設定しておき、各テストコードで使用します。また、GemなのでGemfileに書き込んでbundle installしてやる必要があります。
とりあえず、導入していきましょう。
Gemfileの中の**group :development, test do **の中に記述します
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'rspec-rails', '~> 4.0.0'
gem 'factory_bot_rails'
end
続いてbundle install
% bundle install
実際にFactoryBotを使う
導入が完了したら、続いて、手動で specというディレクトリにfactoriesというディレクトリを作成し、さらにその中にusers.rbというファイルを作成します。これはUserモデルに対するFactoryBotのファイルになります。
spec/factories/users.rbという構造です。
今作成したファイルを下記のように編集します。
FactoryBot.define do
factory :user do
nickname {'test'}
email {'test@example'}
password {'000000'}
password_confirmation {password}
end
end
これでまとめられました。このファイルを使うためにbuildというメソッドを使います。
newメソッドを使って
user = User.new(nickname: 'test', email: 'test@example', password: '000000', password_confirmation: '00000000')
こんなふうにしてたのが、buildを使って先ほどのFactoryBotを使うと
user = FactoryBot.build(:user)
これで同じ記述をしていることになります。だいぶこの方が楽ですよね。
これを使ってテストを書いてみると
require 'rails_helper'
RSpec.describe User, type: :model do
describe 'ユーザー新規登録' do
it 'nicknameが空では登録できない' do
user = FactoryBot.build(:user) # Userのインスタンス生成
user.nickname = '' # nicknameの値を空にする
user.valid?
expect(user.errors.full_messages).to include "Nickname can't be blank"
end
it 'emailが空では登録できない' do
user = FactoryBot.build(:user) # Userのインスタンス生成
user.email = '' # emailの値を空にする
user.valid?
expect(user.errors.full_messages).to include "Email can't be blank"
end
end
end
こんな感じになります。しかし、これでもまだ毎回毎回 user = FactoryBot.build(:user)っていう記述を書くの?ってなりませんか?
そこでbeforeを使います。
テストを書き始める前にbefore do ~ endの間に処理を書くと、テストコード実行前にセットアップしてくれます。
先ほどの定義してたuserという変数はインスタンス変数@userにしてあげないといけませんので注意してください。それでは、これらを踏まえて変更したのが下記になります。
require 'rails_helper'
RSpec.describe User, type: :model do
before do
@user = FactoryBot.build(:user)
end
describe 'ユーザー新規登録' do
it 'nicknameが空では登録できない' do
@user.nickname = ''
@user.valid?
expect(@user.errors.full_messages).to include "Nickname can't be blank"
end
it 'emailが空では登録できない' do
@user.email = ''
@user.valid?
expect(@user.errors.full_messages).to include "Email can't be blank"
end
end
end
このようにまとめると見やすくなりますし、書いてる側も楽ですよね!
最後に下記のコマンドを実行し、テストコードが成功するか確認して終わりにしましょう
% bundle exec rspec spec/models/user_spec.rb
最後に
RspecでFactoryBotを使用は必須かと思います。これも毎回導入しないといけないGemなので導入方法から使い方までしっかり覚えられるようにしていきたいです。