ぺんぎんのRails日記

ぺんぎん。エンジニア経験ゼロ。Rails勉強中。

【RSpec】モデルスペック【Rails】

今日はRSpecとFactoryBotを使ったテストの書き方をまとめます。

はじめてテストを作るので基本から復習します。

テストデータを作る

今回はFactoryBotを使ってテストデータを作ります。 今まではseed.rbでサンプル用のデータを作っていましたが、FactoryBotを使えばテスト用のテストデータを作ることができます。
spec/factories/tasks.rb

FactoryBot.define do
  factory :task do
    sequence(:title, "title_1")
    content { "content" }
    status { :todo }
    deadline { 1.week.from_now }
    association :user
  end
end

カラム名 { カラムの内容 } という書き方になっていますね。

sequence

sequenceを使うと.nextメソッドが呼び出されて、数字を増やしていくことができます。

書き方は2種類あって、

sequence(:title){|n| "title_#{n}"}

sequence(:title, "title_1")

のように書くことができます。
.nextの挙動はこんな感じ。

> "title_1".next
 => "title_2"
> "title_2".next
 => "title_3"

association

モデルがassociationされている時に使えるメソッド。 通常、task.createとuser.createの二つを書く必要がありますが、association :userのように書いておけば、user.createを省略することができます!

同じようにspec/factories/users.rbにもuserのテストデータを作っておきましょう。

テスト要件を書く

いきなりコードを書いていくのではなく、はじめにテストしたい内容を書きます。

RSpec.describe Task, type: :model do
  describe 'validation' do
    it 'is valid with all attributes' do end
    it 'is invalid without title' do end
    it 'is invalid without status' do end
    it 'is invalid with a duplicate title' do end
    it 'is valid with another title' do end
  end
end

☆ポイント☆ 以下の2つに分けてテストを書きます。 ・問題が起きない場合のテスト ・問題が起きる場合のテスト

describeとit

・describeメソッド RSpec.describe 'テストの対象' do

テストをグループ化して、「何についてのテストなのか」を記述する。ここでは、taskモデルについてテストすることを宣言しています。

・itメソッド It "〜" do テストをexampleという単位にまとめてくれています。 It "should be〜"やIt "is 〜"のように書き、It do ... endの中に、エクスペクテーション(期待値と実際の値の比較)を書きます。

exampleの書き方

では、実際にItの中に何を書いていくかを見ていきます。

It is valid with all attributes

「すべてのカラムがある場合に、有効である」というテストをします。

It is valid with all attributes
  task = FactoryBot.build(:task)
  expect(task).to be_valid
  expect(task.errors).to be_empty
end

・task = FactoryBot.build(:task)
taskオブジェクトを作ります。

・expect()には検証したいものを書きます。 expect.to の場合は「〜であること」を期待するときに、expect.not_toの場合は「〜でないこと」を期待するときに使います。 ・be_validはマッチャと呼ばれるものです。意味はその名の通り「有効である」という意味です。その逆で、be_invalidという「無効である」というマッチャもあります。 ちなみに、マッチャとは「期待値と実際の値を比較して、一致した(もしくは一致しなかった)という結果を返すオブジェクト」のことです。 ・be_emptyというマッチャはその名の通り、「空である」という意味のマッチャです。
・(復習)errors[:attribute]はエラーがあったらエラーの配列を返すメソッド。エラーがない場合は空の配列を返します。

It is invalid without title

「タイトルがない場合に無効」という内容でテストします。

 it 'is invalid without title' do
      task_without_title = build(:task, title: "")
      expect(task_without_title).to be_invalid
      expect(task_without_title.errors[:title]).to eq ["can't be blank"]
    end

オブジェクトを変数に代入するときは、役割がわかる名前にしておくと◎
・eqは「等しい」という意味のマッチャです。

FactoryBotの設定

設定に以下を記述しておくと、FactoryBot.createのFactoryBot部分を省略できるようになります。

spec/rails_helper.rb

config.filter_rails_from_backtrace!
  # arbitrary gems may also be filtered via:
  # config.filter_gems_from_backtrace("gem name")

  config.include FactoryBot::Syntax::Methods
end

こんな感じでtask = build(:task)書けるようになっていい感じですね。

とりあえず、今回はここまでとします! おやすみなさい🐧🌙