🐥

RSpec の基本的な流れ

2024/07/29に公開

テストが少しずつ書けるようになってきたので、基本的な流れを整理!
まだ基本的なことしか学べていないので、参考までに🙇

テストの流れ

  1. テストの対象クラス(RSpec.describe)
  2. テストの対象メソッド(describe)
  3. 特定の条件における実行(context)
  4. 期待する結果(it, expect)

「新規ユーザーの場合はUserテーブルにユーザーを追加し、既存ユーザーの場合はUserテーブルのユーザーを更新」のような実装のテストを考える

RSpec.describe UserCreateOrUpdate do
  let!(:user) { User.new }

  describe "#call" do
    it "callメソッドが成功し、Userテーブルに追加される" do
      expect {
        expect(operation.call).to be true
      }.to change(User, :count).by(1)
    end

    context "そのuserが既に存在する時" do
      let!(:existing_user) { User.new(name: "Tom", age: 23) }

      it "callメソッドが成功し、existing_userが更新される"
      expect(operation.call).to be true

      expect(existing_user.reload).to have_attributes(
        name: "Tom",
        age: 23,
      )
    end
  end
end

説明

RSpec.describe

RSpec.describe UserCreateOrUpdate do

UserCreateOrUpdateというクラスについてテストしますよ!ということ
RSpec.describedescribeの両方の書き方があるっぽいけど、RSpec.describeの書き方が主流になってきているらしい
https://wai-doi.hatenablog.com/entry/rspec-describe

describe

describe "#call" do

UserCreateOrUpdateというクラスの中のcallメソッドについてテストします!ということ

it

it "callメソッドが成功し、Userテーブルに追加される" do

itは、実行して期待されることのまとまり
ここでは、「callメソッドが成功し、Userテーブルに追加される」ようになるはず(期待)!ということ
この中に、詳しい内容を書いていく

expect

expect {
  expect(operation.call).to be true
}.to change(User, :count).by(1)

expectを使って、期待される具体的な内容を書く
ここで書かれているのは、「callオペレーションが成功し、Userテーブルに1件追加される」という内容
expect()expect{}の違いは、以下を参照 ↓
https://libitte.hatenablog.jp/entry/20141129/1417251425

context

context "そのuserが既に存在する時" do
  let!(:existing_user) { User.new(name: "Tom", age: 23) }

contextは、特定の条件下で実行して期待されることのまとまり
ここでは、「userが既に存在する」という条件下なので、その条件である既存ユーザーをlet!(:existing_user) { User.new(name: "Tom", age: 23) }で定義している

ここで、let!とはテストコンテキスト内でのみ有効な一時的な変数を定義するメソッド
ちなみに、letlet!の違いは以下を参照↓
https://zenn.dev/kyohei_shibuya/articles/722891a1a6648a

  expect(existing_user.reload).to have_attributes(
    name: "Tom",
    age: 23,
  )

ここでは、「userが既に存在する」という条件、つまり更新を行う
更新を行うユーザーは先ほど定義したexisting_userなので、Userテーブルのexisting_userのnameとageが定義したもの(Tomと23)になっているかの確認を行なっている

その他

before

前提条件や、テスト実行前に実行したいことなどに使う
https://yamaguchi-web.com/2022/02/04/rails-rspec-before-do/

subject

引数が必要なメソッドのテストに使う
https://qiita.com/kyoryu_san/items/51aa1b124b6caaabffa8

参考

https://zenn.dev/yuji_developer/articles/52cc0e356b3748
https://qiita.com/uchiko/items/d34c5d1298934252f58f

Discussion