プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • Rspec
  • 【Rspec】「FactoryBot」の構文について
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【Rspec】「FactoryBot」の構文について

03.15

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

テンプレート側

テストデータに連番をつける。(シーケンス)

通常は、FactoryBot.createやFactoryBot.buildを複数回実行した場合は常に同じデータができますが、下記のようにsequenceを使うことで複数回データを作成した際に連番データを作成することが可能です。

1
2
3
4
5
FactoryBot.define do
  factory :モデルクラス名 do
    sequence(:カラム名) { |n| "ここに#{n}連番を挿入" }
  end
end

絶対に複数データを使うとわかっているカラム等に関しては上記の機能を使用するとRspecの記述もすっきりすると思います。

モデル同士を関連づけてデータを生成する。

下記のように記述するとFactoryBot.createを実行すると同時に所属するモデルまで自動で生成してくれます。いちいちテストコード側で関連するモデルの生成処理を記述しなくてよくなります。

1
2
3
4
5
FactoryBot.define do
  factory :モデルクラス名 do
    association :本モデルが所属するモデル名
  end
end

別名をつける。

モデル側(app/models/モデル名.rb)でモデルを別名で参照するようなソースになっていた場合は下記のように記述してモデルの仕様に合わせる必要があります。

1
2
3
4
FactoryBot.define do
  factory :user, aliases: [:別名] do
  end
end

複数ファクトリを作る。

下記のように記述すればファクトリを複数作成してテストコード内で使用することが可能です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FactoryBot.define do
  factory :ファクトリ名 do
    属性1: 属性値1
    属性2: 属性値2
  end
 
  factory :ファクトリ1,class: クラスのインスタンス名(User等) do
    属性1: 属性値1
    属性2: 属性値2
  end
 
  factory :ファクトリ2,class: クラスのインスタンス名(User等) do
    属性1: 属性値1
    属性2: 属性値2
  end
 
  factory :ファクトリ3,class: クラスのインスタンス名(User等) do
    属性1: 属性値1
    属性2: 属性値2
  end
end

テンプレートの重複を排除する。

継承による重複排除

テンプレート側の記述方法

上のコードだとFactoryBotの記述がかなり冗長になっていますが、下記のように記述すればすっきり記述できます。構造から使うクラスがわかるためclass指定も必要なくなります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FactoryBot.define do
  factory :親ファクトリ名 do
    属性1: 属性値1(子ファクトリにも継承される)
    属性2: 属性値2(子ファクトリにも継承される)
 
    factory :子ファクトリ1 do
     属性2': 属性値2'(オーバーライド)
    end
 
    factory :子ファクトリ2 do
      属性2': 属性値2'(オーバーライド)
    end
 
    factory :子ファクトリ3 do
      属性2': 属性値2'(オーバーライド)
    end
  end
 
end

テストコード側の記述方法

1
FactoryBot.create(:子ファクトリ1)

トレイト(trait)を使った重複排除

テンプレート側の記述方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FactoryBot.define do
  factory :親ファクトリ名 do
    属性1: 属性値1(子ファクトリにも継承される)
    属性2: 属性値2(子ファクトリにも継承される)
 
    trait :子ファクトリ1 do
     属性2': 属性値2'(オーバーライド)
    end
 
    trait :子ファクトリ2 do
      属性2': 属性値2'(オーバーライド)
    end
 
    trait :子ファクトリ3 do
      属性2': 属性値2'(オーバーライド)
    end
  end
 
end

テストコード側の記述方法

テストコード側の記述が継承を使用する場合に比べて少し変わります。

1
FactoryBot.create(:モデル名,:子ファクトリ1)

継承とトレイトの違い

  • トレイト同士を組み合わせて複雑なオブジェクトを構築できる点(継承ではできない)

コールバック

FactoryBotでcreate、build、stubする前やした後に追加のアクションを実行することができる機能です。

メリット

  • 適切にコールバックを使うことによって複雑なテストシナリオも簡単にセットアップすることが可能になる。
  • モデルが入れ子になっており他のモデルの属性を持っている場合とかのデータ作成に使えます。

例

下記のように記述すればFactoryBot.createを実行した後に処理内容を実行してくれます。

1
after(:create等のテストコード側のメソッド) { 処理内容(例:create_list等で複数インスタンスを作る等)}

注意点

コールバックで関連するデータを準備する場合はFactoryBot.createよりはFactoryBot.buildを使った方が良い。データベースに挿入する回数が減ってパフォーマンスが上がります。

Rspec(テストコード側)

FactoryBot.create

新しいデータを作成する。(DBに保存されます。)

用途

Rspecではデータベースに保存されるので保存されたデータを活用して重複登録チェックとかをしたい場合に活用したりします。

例

1
2
3
4
#下記例は重複エラーになる。
FactoryBot.create(:user, email:"test@example.com")
user = FactoryBot.build(:user, email:"test@example.com")
user.valid?

FactoryBot.build

新しいデータをインスタンス化する。(DBに保存はされません。)

用途

Rspecでは一時的にローカル変数に保存してデータを活用したい等の目的で使用したりします。

例

1
2
3
#userオブジェクトの有効性(不正な値でインスタンスが作成されていないか)をチェックする。
user = FactoryBot.build(:user)
user.valid?

FactoryBot.attributes_for(設定値)

パラメータを設定する。実際は指定したモデルのファクトリからテスト用の属性値のハッシュを作成します。その後に属性値を具体的に指定すれば値を上書きすることも可能です。

例

1
2
params = FactoryBot.attributes_for(:モデルのファクトリ)
post :create, params: { モデル名: params }
スポンサーリンク
  • 2020 03.15
  • miyabisan2
  • コメントを書く
  • Rspec
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2020 03.20

    【Rspec】「サポートモジュール」での共通化、DRY原則

  2. 2019 12.01

    【Rspec】バージョン、設定ファイル(.rspec)、全体像を把握する。

  3. 2020 03.21

    【RSpec】「Shoulda Matchers」について

  4. 2019 12.30

    【Rspec】「Controller Spec(コントローラスペック)」の基本

  5. 2020 03.21

    【RSpec】高速化の手法(ParallelTestsなど)

  6. 2019 12.01

    【Rspec】RspecのインストールやRailsで使うための準備や実行方法

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【Ruby on Rails】「フィクスチャ」について

【Rspec】Capybaraについて

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Git
  • GitLab
  • GraphQL
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • WebRTC
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー