【RSpec】FactoryBotを使ってみよう【Rails】


 Factory Botとは??

  • テストのためのデータを簡単に作成できるライブラリ
  • Active Record を使う

 Factory Botのあれこれ

factory_bot_railsをインストールすると、下記のようなコマンドでfactoryを作成するためのファイルを作ることができます。

bin/rails g factory_bot:model task

少し解説します。

bin/rails gまでは大丈夫でしょう。factory_bot:modelでモデルに明示します。taskのように対象を指定してあげてください。

このコマンドを実行すると、spec/factories/tasks.rbに以下のようなファイルが生成されると思います。

spec/factories/tasks.rb
FactoryBot.define do

  factory :task do

  end
end

雛形ができましたね。この中にデータを定義していきましょう。

spec/factories/tasks.rb
FactoryBot.define do

  factory :task do
    name "お買い物"
    content "夕飯を買いに行く"
  end
end

少ないかもしれませんが、まあ大丈夫でしょう。 テストファイル内でFactoryBot.create(:task)と実行することで、spec/factories/tasks.rbに記述した内容のデータを作成することができます。

 FactoryBotを少しだけ使いこなす。

 オーバーライドさせる

例えば、tasknamenilだった時にエラーを出力させる異常系のテストを書きたい場合は、下記のように書けます。

spec/models/task_spec.rb
# nameがなければ、無効。
it "is invalid without a name" do
  task = FactoryBot.build(:task, name: nil)
  task.valid?
  expect(task.errors[:name]).to include("can't be blank")
end

プロパティを上書きしてnilにすることで、期待通りの形にしています。

 ユニークな値を扱う。

例えばメアドは唯一無二であるはずだし、そのような仕様であり、そのようなテストを書くべきです。しかし、FactoryBotは常に同じ値を参照するので、そのような事象に対応できない場合があります。

この問題をは下記のようにシーケンスを使うことで解決できます。

spec/factories/users.rb
FactoryBot.define do

  factory :user do
    name "山田"
    sequence(:email) { |n| "test#{n}@example.com" }
  end
end

このように定義することによって、[email protected][email protected]のように設定されます。

とても便利。