⭐︎RSpec

RSpecの復習

内容

今回はRSpec編で自分の理解が浅い部分を復習していきます。

FactoryBotの設定
spec/rails_helper.rb

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods

end

config.include FactoryBot::Syntax::Methodsをhelperに設定する事によって、
rspecのテストコード中でFactory_botのメソッドを使用する際に、クラス名の指定を省略できるようになります。

・例

 # 通常FactoryBotをつけないと、メソッドを呼べない
 user = FactoryBot.create(:user)

 # 上の設定を追加することで、FactoryBotの記述が省略できる。
 user = create(:user)
FactoryBot.define do
  factory :user do
    sequence(:name) { |n| "TEST_NAME#{n}"}
    sequence(:email) { |n| "TEST#{n}@example.com"}
  end
end

sequenceを付ける事によって、対象のFactoryをcreate_listなどで複数件作成した時にnameのunique制約で失敗する事を防ぐ。

traitについて

・テストデータ(ファクトリー)を作る際に、
「何かのカラム(emailやstatusなど)だけ違う値を作りたいな」と思った時に使う機能。(重複を防ぐ)

例えば、「10個のインスタンスがある内の1個だけ属性値を変えたい」時にtraitを使い定義する。

定義したファクトリをspecファイルで呼び出したい時は、以下のように記述します。

user_spec.rb
  
user = FactoryBot.create(:user(モデル名), :another_user(ファクトリ名))
letついて

factoryファイルを元にDBにユーザ情報を作成。

let文の書き方
let(:変数) { 処理したい内容 }


let(:task) { create(:task, project_id: project.id) }

 # @userというインスタンス変数に代入  
before do
  @user = create(:user)
end
  
# userという変数に代入
let(:user) { create(:user) }
◯◯_spec.rb
describe 'let' do
  let(:user) { create(:user) }
  let(:user_article) { create(:article, user_id: user.id) }

  specify 'User が Article を持っていること' do
    expect(user.articles.first).to eq user_article
  end
end

上記のような場合、let(:user_article) { create(:article, user_id: user.id) }
が呼ばれるのは、
expect(user.articles.first).to eq user_article
の中で "user_article" が呼ばれた時で
"user.articles.first" が処理される時にはまだ実行されていないので "user.articles.first" は空となりテストは通らない。
この事を遅延評価と呼ぶ。

letを各サンプルが実行される前に評価したい場合(it文やspecity文など)は
let!(:user_article) { create(:article, user_id: user.id) }
のようにしてあげる。

特定のuserでログインできるマクロを作成

色々なユーザでログインする処理を共通化するために、特定のuserを渡すことでログインができるマクロを追加します。

spec/support/login_macros.rb

module LoginMacros
   def login(user)
     visit admin_login_identifier_path
     fill_in 'user[name]', with: user.name
     click_button('次へ')
     # DB上では暗号化されて crypted_password に保存されているため user.password で取り出せないので、直接文字列で password を渡す
     fill_in 'user[password]', with: 'password'
     click_button('ログイン')
   end
 end

このマクロを使用できるように、設定を追加します。

spec/rails_helper.rb

RSpec.configure do |config|
  # 省略
  
  config.include LoginMacros
end