第2のモデルのテストを追加する: 小林研 Rails Tips (64)

このページの内容は以下のリポジトリに1日遅れで反映されます(記事執筆前に前日分をコミットしています)。

https://github.com/hkob/hkob_blog

はじめに

Rails Tips の 64 回目です。昨日追加した Comment モデルのテストを記載します。

Rails をはじめよう - Railsガイド

モデルの関連テスト

昨日モデルは追加しましたが、まだ何も機能を追加していません。まず最初に属性に関するテストをまとめて実施します。body の長さのチェックは article と同じものです。まだ shared_example に追加していないものは、こちらで紹介しています。

require "rails_helper"

RSpec.describe Comment, type: :model do
  let(:comment) { comments :comment }
  let(:can_delete) { comments :can_delete }

  context "属性に関する共通テスト" do
    subject { can_delete }
    it_behaves_like "存在制約", %i[commenter body article_id]
    it_behaves_like "削除可能制約"
    it_behaves_like "関連確認", :comment, has_many: %i[article]
    it_behaves_like "親削除時に自分も削除", :comment, %i[article]

    describe "body length check" do
      context "body is 10 characters" do
        before { subject.body = "a" * 10 }
        it { is_expected.to be_valid }
      end

      context "body is 9 characters" do
        before { subject.body = "a" * 9 }
        it { is_expected.to be_invalid }
      end
    end
  end

  (後略)

fixture データは spec/fixtures/comments.yml に以下のように記述しました。

comment1:
  commenter: "user 1"
  body: "comment 1 for article 1"
  article: article1

can_delete:
  commenter: "user 2"
  body: "comment 2 for article can_delete"
  article: can_delete

最初は「存在制約」です。commenterbodypresence 制約がありません。追加するとエラーが消えました。

    behaves like 存在制約
      is expected to be valid
      commenter の内容が nil のとき、エラーになること (FAILED - 1)
      body の内容が nil のとき、エラーになること (FAILED - 2)
      article_id の内容が nil のとき、エラーになること

残りは「関連確認」と「親削除時に自分も削除」です。現在、comment.rbbelongs_to は書かれていますが、article.rb の方に has_many がありません。今回は、dependencydestroy として子供も同時に消すことにします。

    behaves like 関連確認
      commentを削除するとき
        article.comments.count が1つ減ること (FAILED - 1)
    behaves like 親削除時に自分も削除
      comment.articleを削除したとき
        関連により自分自身も削除されること (FAILED - 2)

最後に body の長さのテストです。こちらも、body に対して長さの validates を追加することでエラーがなくなります。

    body length check
      body is 10 characters
        is expected to be valid
      body is 9 characters
        is expected to be invalid (FAILED - 1)

comment.rb の実装はこちらです。

class Comment < ApplicationRecord
  validates :commenter, presence: true
  validates :body, presence: true, length: { minimum: 10 }
  belongs_to :article
end

また、article.rb は has_many が追加されています。

class Article < ApplicationRecord
  validates :title, presence: true
  validates :body, presence: true, length: { minimum: 10 }
  has_many :comments, dependent: :destroy
end

おわりに

これで、関連に関するテストも追加しました。属性以外のテストについては、また後日解説します。