見出し画像

[output] FactoryBot と Faker

●FactoryBot

Rspecでテストを行うにあたり、
テスト毎にインスタンスを生成するのは
非効率かつ、可読性が落ちる。

そのためFactoryBotというGemを使用し、
テストで使用するインスタンスをあらかじめ設定しておく。

導入方法は、まずGemfileに下記を記述。

group :development, :test do
 # Call 'byebug' anywhere in the code to stop execution and get a debugger console
 略
 gem 'factory_bot_rails'
end

その後、bundle installを行う。

FactoryBot導入後に、
テストファイルを生成する場合は以上で導入は完了となる。

これは、テストコードを記述するファイルを作成したら、
自動で必要なファイルを生成してくれるためである。

FactoryBot導入前に
テストファイルを生成している場合は、
続けて下記設定が必要となる。

specディレクトリ以下に、「factories」ディレクトリを作成。
そこに、インスタンスを設定したいクラス名のファイルを作成する。
例)Userクラスのインスタンスならば、「users.rb」

状況に応じてインスタンスを使い分ける、
すなわち複数のインスタンスを管理するため
クラス名が複数形となっていることに留意する。

ファイルが用意できたら、テストコードで使用するインスタンスを設定する。

#spec/factories/models.rb

FactoryBot.define do
 factory :class do
   password             {'00000000'}
   e-mail               {'test@example'}
 end
end

クラス名を :classで指定し、
do~end内に属性(=テーブルのカラム名)と、
設定したい値を{}内に記述する。

設定したインスタンスの生成方法は、下記の通り。

class = FactoryBot.build(:class)

buildを用いて、インスタンスを生成する。
FactoryBotのbuildは、RailsにおけるActiveRecordのnewメソッドと
同様の働きをする。

また、このFactoryBotを使用したインスタンス生成コードを
Rspecのbefore内に記述することで
コードがよりスッキリとする。

require 'rails_helper'
RSpec.describe User, type: :model do
 before do
   @class = FactoryBot.build(:class) 
 end

 describe 'X' do
   it 'Y' do
     # before内の処理が完了してから実行される
   end
 end
end

注意事項としては、before内で定義した変数を
before外で使用するには、インスタンス変数として定義すること。


●Faker

また、FactoryBotで設定したインスタンスの値には
{'test'}などと、任意の値を設定していたが、
ここにランダム生成した値を設定することができる。

それは、FakerというGemで実現する。
これは、ランダムな値を生成するGemで、
ランダム生成する値は、広く対応している。

こちらの導入方法は、Gemfileに下記を記述し、bundle install。

group :development, :test do
 # Call 'byebug' anywhere in the code to stop execution and get a debugger console
 略
 gem 'faker'
end

以上で、使用可能となる。

記述方法は、GitHubのドキュメントに詳細が載っている。
例えば、下記の通り。

 Faker::Internet.free_email
=> メールアドレスの生成

Faker::Internet.password(min_length: 6)
=> 6文字以上のパスワードの生成

FactoryBotで設定した記述を書き換えると、
こうなる。

#spec/factories/models.rb

FactoryBot.define do
 factory :class do
   password             {Faker::Internet.password(min_length: 6)}
   e-mail               {Faker::Internet.free_email}
 end
end