[Rails] Rspecでcreate_listを使って複数のインスタンスを作成する方法

学習記録

はじめに

下記のようにtaskのFactoryBotが定義されているとします。

FactoryBot.define do
  factory :task do

    sequence(:title, "title_1")
    content { 'Content' }
    status { 'todo' }
    deadline { 1.week.from_now }
    association :user
  end
end

Rspecを書く場合に一覧画面などの検証を行う際、複数のインスタンスが欲しい場合がありますが、このように一つずつ作るのは面倒です。一括で作成できる方法があれば便利ですね。

let(:task1) { create(:task) }
let(:task2) { create(:task) }
let(:task3) { create(:task) }

create_listメソッドを使う

crete_listはFactoryBotで用意されているメソッドです。作成されたインスタンスは配列になります。
第1引数にファクトリ名、第2引数に作成する数を指定します。

tasks = create_list(:task, 3)

また、明示的にカラムの要素を書くことで上書きすることもできます。

tasks = create_list(:task, 5, title: 'sample_title', content: 'sample_content')

せっかくなのでコンソールで確認します。

$ rails console test --sandbox                                                                                   ?03_system_spec
Running via Spring preloader in process 22849
DEPRECATION WARNING: Passing the environment's name as a regular argument is deprecated and will be removed in the next Rails version. Please, use the -e option instead. (called from <main> at /Users/takahashishuuhei/workspace/runteq/rspec_beginner/sample_app_for_rspec/bin/rails:9)
Loading test environment in sandbox (Rails 5.2.3)
Any modifications you make will be rolled back on exit
irb(main):001:0> require 'factory_bot_rails'
include FactoryBot::Syntax::Methods
=> false
=> Object
irb(main):003:0> task_list = create_list(:task, 3)
   (0.1ms)  SAVEPOINT active_record_1
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "user_1@example.com"], ["LIMIT", 1]]
  User Create (0.3ms)  INSERT INTO "users" ("email", "crypted_password", "salt", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["email", "user_1@example.com"], ["crypted_password", "$2a$04$IeyRhAHB9OKc9cvql7VEF..bwkC./4kifD0EOPBgem.y5Aoh231ZK"], ["salt", "jDzqzMPSufzcLYskpAyu"], ["created_at", "2021-10-27 04:06:33.243451"], ["updated_at", "2021-10-27 04:06:33.243451"]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.1ms)  SAVEPOINT active_record_1
  Task Exists (0.1ms)  SELECT  1 AS one FROM "tasks" WHERE "tasks"."title" = ? LIMIT ?  [["title", "title_1"], ["LIMIT", 1]]
  Task Create (0.1ms)  INSERT INTO "tasks" ("title", "content", "status", "deadline", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)  [["title", "title_1"], ["content", "Content"], ["status", 0], ["deadline", "2021-11-03 04:06:33.211247"], ["created_at", "2021-10-27 04:06:33.248298"], ["updated_at", "2021-10-27 04:06:33.248298"], ["user_id", 1]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.0ms)  SAVEPOINT active_record_1
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "user_2@example.com"], ["LIMIT", 1]]
  User Create (0.1ms)  INSERT INTO "users" ("email", "crypted_password", "salt", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["email", "user_2@example.com"], ["crypted_password", "$2a$04$KNQwkHsLNm3Efaj58kw2h.SXUok9HZUtz2z7l3zgEc9nb95nA0WUC"], ["salt", "hbMX-XoYfyHTGtJzJi2L"], ["created_at", "2021-10-27 04:06:33.257352"], ["updated_at", "2021-10-27 04:06:33.257352"]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.0ms)  SAVEPOINT active_record_1
  Task Exists (0.1ms)  SELECT  1 AS one FROM "tasks" WHERE "tasks"."title" = ? LIMIT ?  [["title", "title_2"], ["LIMIT", 1]]
  Task Create (0.1ms)  INSERT INTO "tasks" ("title", "content", "status", "deadline", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)  [["title", "title_2"], ["content", "Content"], ["status", 0], ["deadline", "2021-11-03 04:06:33.249477"], ["created_at", "2021-10-27 04:06:33.258847"], ["updated_at", "2021-10-27 04:06:33.258847"], ["user_id", 2]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.0ms)  SAVEPOINT active_record_1
  User Exists (0.1ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "user_3@example.com"], ["LIMIT", 1]]
  User Create (0.1ms)  INSERT INTO "users" ("email", "crypted_password", "salt", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?)  [["email", "user_3@example.com"], ["crypted_password", "$2a$04$9JeRfyYO98GECl4VUPhiP.mzIbFHO2ZhZzYUfHbLa6DxK7Bshfao6"], ["salt", "fdztpGJ5zyoa1dKdqNfR"], ["created_at", "2021-10-27 04:06:33.267587"], ["updated_at", "2021-10-27 04:06:33.267587"]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.0ms)  SAVEPOINT active_record_1
  Task Exists (0.1ms)  SELECT  1 AS one FROM "tasks" WHERE "tasks"."title" = ? LIMIT ?  [["title", "title_3"], ["LIMIT", 1]]
  Task Create (0.1ms)  INSERT INTO "tasks" ("title", "content", "status", "deadline", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?)  [["title", "title_3"], ["content", "Content"], ["status", 0], ["deadline", "2021-11-03 04:06:33.259784"], ["created_at", "2021-10-27 04:06:33.269019"], ["updated_at", "2021-10-27 04:06:33.269019"], ["user_id", 3]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1
=> [#<Task id: 1, title: "title_1", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 1>, #<Task id: 2, title: "title_2", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 2>, #<Task id: 3, title: "title_3", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 3>]

task_list
=> [#<Task id: 1, title: "title_1", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 1>, #<Task id: 2, title: "title_2", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 2>, #<Task id: 3, title: "title_3", content: "Content", status: "todo", deadline: "2021-11-03 04:06:33", created_at: "2021-10-27 04:06:33", updated_at: "2021-10-27 04:06:33", user_id: 3>]

一応補足ですが、コンソールでFactoryBotを使用したときは、require 'factory_bot_rails'を入力しなければ使うことはできません。

$ require 'factory_bot_rails'
include FactoryBot::Syntax::Methods

コメント

タイトルとURLをコピーしました