0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rails] テストコードでFactoryBotを使う

Posted at

はじめに

前回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 **の中に記述します

Gemfile
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という構造です。

今作成したファイルを下記のように編集します。

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)

これで同じ記述をしていることになります。だいぶこの方が楽ですよね。
これを使ってテストを書いてみると

spec/models/user_spec.rb
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にしてあげないといけませんので注意してください。それでは、これらを踏まえて変更したのが下記になります。

spec/models/user_spec.rb
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なので導入方法から使い方までしっかり覚えられるようにしていきたいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?