2
3

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.

FactoryBot & Fakerの導入 (Rspecでの使い方)

Last updated at Posted at 2021-02-25

初学者です。備忘録がてらまとめました。

  • Ruby2.6.5
  • Rails6.0.0

テストコードを効率的に書きたい!

テストコードが冗長になって読みにくい..そんな時に使えるFactoryBot!
例えばUserのログイン機能をテストしたいとします。

以下が使ってないverです。

RSpec.describe User, type: :model do
  describe 'ユーザー新規登録' do
    it 'nicknameが空では登録できない' do
      user = User.new(nickname: '', email: 'test@example', password: '000000', password_confirmation: '000000')
      user.valid?
      expect(user.errors.full_messages).to include("Nickname can't be blank")
    end

次にFactoryBot使用verです。

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

FactoryBotとは、インスタンスをまとめるGemのことです。別ファイルに書き込んだものを、書くテストコードで使い回しできるんです。

めっちゃ変わった!というわけではありませんが、目視でわかりますね。使ってないと横に伸びてます。

このコードだけだと、効果がわかりづらいのですが、テストコードはあら有る状況を書いていくもの..
FactoryBotを使わないと、チリも詰まればなんとやらと言いますが、まさしくそれで、可読性も下がってしまいます。

ですので、テストコードを書く際は積極的に使いましょう!

FactoryBotの導入

Gemの一種ですので、いつもの流れです。
が、記述する箇所に注意してください!
Gemfileのgroup :development, :test do ~ end
の中です。
Rspecと同じ箇所ですね。

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を書く、もしくはインスタンスをまとめるファイルを作成します。
※ここではUserモデルのテストコードで進めていきます。

spec/factories /users.rb ←これを作ります

具体的な書き方

生成したファイル内の記述例がこちらです。
Fakerを使用したほうが良いパターンもあります。詳しくはこの後に記述しています。

spec/factories/users.rb

FactoryBot.define do
  factory :user do
    nickname              {'test'}
    email                 {'test@example'}
    password              {'000000'}
    password_confirmation {password}
  end
end

この設定したインスタンスをテスト内で使う場合、 FactoryBot.build(:user) と書く必要があります!

さっき上で見たテストコードを使って修正します。

spec/models/user_spec.rb

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

これをさらに可読化させます。

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

@userとbeforeを活用することで、**user = FactoryBot.build(:user)**を繰り返し書かずに済みます。

ここで beforebuild が出てきたので簡単に触れましょう。

before

それぞれのテストコードを実行する前に、先に実行してくれます。コントローラーでもたまに使ってましたね!
今回はこのbeforeくんのおかげでちゃっちゃと記述できています。とっても効率的!

build

ActiveRecordのnewメソッドと同じように働きます。
build=組み立てる、築くって意味ですもんね!

テストコードがかけたら、下記のコマンドを実行します。

ターミナル

bundle exec rspec spec/models/user_spec.rb 

値をランダム生成するFaker

ここまでは、FactoryBot内の詳細を自分で記述していました。(email=test@example、nickname=testなど)
ですが、もしemailなどのバリデーションで一意性などの設定をしていた場合、このままだとテストが通らなくなってしまいます。

そんな時に使うのがFakerです!

Faker

ランダムな値を生成するGemです。メールアドレス、人名、パスワードなど、さまざまな意図に応じたランダムな値を生成してくれます。

Fakerの公式GitHub
Qiita・Fakerのチートシート

Fakerの導入

こちらもGemfileに記述し、bundle installしましょう!
今回も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'
  gem 'faker'
end

Fakerバージョンに記述を変更してみる

emailだけでもいいのですが、せっかくですから三つともFakerバージョンにしてみましょう!

spec/factories/users.rb

FactoryBot.define do
  factory :user do
    nickname              {Faker::Name.initials(number: 2)}
    email                 {Faker::Internet.free_email}
    password              {Faker::Internet.password(min_length: 6)}
    password_confirmation {password}
  end
end

テストしてみましょう。

ターミナル

% bundle exec rspec spec/models/user_spec.rb 

緑色で通れば成功です!
お疲れ様でした!

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?