5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RSpecテストにおける build と create の使い分け

Last updated at Posted at 2024-07-25

はじめに

RSpecでテストを書く際、FactoryBotを使用してテストデータを生成することが一般的です。その際、buildcreate という2つのメソッドがよく使われますが、これらの使い分けは重要です。本記事では、これらのメソッドの違いと適切な使用場面について解説します。

buildcreate の基本的な違い

build

  • メモリ上にオブジェクトを作成するが、データベースには保存しない
  • 処理が高速
  • データベースに影響を与えない

create

  • オブジェクトを作成し、データベースに保存する
  • build より処理が遅い
  • データベースに実際にレコードが作成される

使い分けの指針

buildを使用する場合

  1. モデルの単純なバリデーションをテストする場合
  2. データベースへの保存が不要なテストの場合
  3. テストの実行速度を重視する場合

例:

RSpec.describe User, type: :model do
  let(:user) { build(:user) }

  it "有効なユーザーであること" do
    expect(user).to be_valid
  end

  it "名前がない場合は無効であること" do
    user.name = nil
    expect(user).to be_invalid
  end
end

createを使用する場合

  1. データベースレベルの制約(一意性など)をテストする場合
  2. 関連するモデルとの相互作用をテストする場合
  3. データベースに保存された後の挙動をテストする場合
  4. type: :request のテストなど、実際のアプリケーション動作に近い環境でテストする場合

例:

RSpec.describe "Users", type: :request do
  let(:user) { create(:user) }

  it "ユーザー情報を取得できること" do
    get user_path(user)
    expect(response).to have_http_status(:success)
  end
end

テストタイプ別の推奨使用方法

  1. Model Spec (type: :model)

    • 主に build を使用
    • データベースレベルの制約をテストする場合は create を使用
  2. Request Spec (type: :request)

    • 主に create を使用
    • 実際のHTTPリクエストをシミュレートするため、データベースにデータが存在する状態が望ましい
  3. Controller Spec (type: :controller)

    • 状況に応じて build と create を使い分ける
    • データベースとの相互作用が必要な場合は create を使用
  4. View Spec (type: :view)

    • 主に build を使用
    • ビューのレンダリングのみをテストする場合はデータベースへの保存は不要

まとめ

buildcreate の適切な使い分けは、テストの目的、対象となる機能、パフォーマンスの要件などを考慮することが必要だと思います。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?