DK’s diary

プログラミング初学者による発信

Rspecによるテスト:factory_botによるインスタンスの生成

factory_botとは

Rspecでテストを書いていて、
一回一回対象のインスタンスを生成(User.newのところ)するのは面倒です。
こんな感じで↓↓(例はUserモデルの単体テスト

require 'rails_helper'
describe User do
  describe '#create' do
    it "usernameがないと登録できない" do
      user = User.new(username: "", email: "test@test.com", password: "111111", password_confirmation: "111111")
      user.valid?
      expect(user.errors[:username]).to include("が入力されていません。")
    end

    it "emailがないと登録できない" do
      user = User.new(username: "テストさん", email: "", password: "111111", password_confirmation: "111111")
      user.valid?
      expect(user.errors[:email]).to include("が入力されていません。")
    end
  end
end

そこで便利なのが今回の主役 "factory_bot"
予めインスタンスの情報を記述しておけば、
User.newでいちいちインスタンスを生成せずに、
buildやcreateといったメソッドで簡単に呼び出すことができます。
(buildとcreateについては後述します。)


factory_botの導入

まずGemfileに以下を記述します。

Gemfile

gem 'factory_bot_rails'


bundle install を忘れずに!

次にファイルの作成です。
specディレクトリ直下にfactoriesというフォルダを作成し、
その配下にそれぞれのファイルを置いていくというのが慣例みたいです。
今回の例であればusers.rbファイルを新規作成します。
中身を書いていきます。

spec > factories > users.rb

FactoryBot.define do
  factory :user do
    username              {"テストさん"}
    email                 {"test@test.com"}
    password              {"111111"}
    password_confirmation {"111111"}
  end
end

これであとは呼び出すだけです。


factory_botの呼び出し
user = FactoryBot.build(:user)

作成したインスタンスは上記の記述で生成されます。
今回はbuildメソッドですが、createメソッドでも生成されます。
createメソッドの場合は一時的にテスト用のDBにデータが保存されます。
例えば一意性の確認の時に、最初にcreateメソッドで1人目を登録しておくことで、
2人目が同じ内容を登録した時にバリデーションが働いているかを確認することができます。


そして、FactoryBotという記述を省略することができます。
そのためにはrails_helper.rbファイルに以下を記述しましょう。
このファイルはRspecrailsにインストール後、
ターミナルにて"rails g rspec:install" で生成されるファイルの一つです。

spec > rails_helper.rb

RSpec.configure do |config|
# 下記を追記
  config.include FactoryBot::Syntax::Methods

最終的にはこうなります。

# factory_bot導入前
user = User.new(username: "テストさん", email: "test@test.com", password: "111111", password_confirmation: "111111")

# factory_bot導入後
user = build(:user)

かなりスリムになりました!


ちなみに、特定の箇所を変更したい場合はこう記述します。

user = build(:user, username: "")

これでusernameが空のインスタンスが生成されることになります。