RSpec の基本的な流れ
テストが少しずつ書けるようになってきたので、基本的な流れを整理!
まだ基本的なことしか学べていないので、参考までに🙇
テストの流れ
- テストの対象クラス(RSpec.describe)
- テストの対象メソッド(describe)
- 特定の条件における実行(context)
- 期待する結果(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.describe
とdescribe
の両方の書き方があるっぽいけど、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{}
の違いは、以下を参照 ↓
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!とはテストコンテキスト内でのみ有効な一時的な変数を定義するメソッド
ちなみに、let
とlet!
の違いは以下を参照↓
expect(existing_user.reload).to have_attributes(
name: "Tom",
age: 23,
)
ここでは、「userが既に存在する」という条件、つまり更新を行う
更新を行うユーザーは先ほど定義したexisting_user
なので、Userテーブルのexisting_user
のnameとageが定義したもの(Tomと23)になっているかの確認を行なっている
その他
before
前提条件や、テスト実行前に実行したいことなどに使う
subject
引数が必要なメソッドのテストに使う
参考
Discussion