STIを使っている時のFactoryBotでのモックデータの作成

こんにちは!kossyです!




さて、今回はSTI(SingleTableInheritance)を使ってクラス定義をしているクラスの
FactoryBotでのモックデータの作成の仕方について、ブログに残してみたいと思います。




環境
Ruby 2.5.1
Rails 5.2.3
MacOS Mojave




なお、STIが何かについての説明は割愛します。
みんなRailsのSTIを誤解してないか!? - Qiita
[Rails] STI(単一テーブル継承)とメタプログラミングでDRY - Qiita

STIについて詳しく知りたい方は上記の記事をご覧になってみてください。




initialize_withメソッドを使う

例えば、STIで、
親 Commentクラス
子 ArticleComment, EntryCommentクラス

が定義されているとします。

この場合、

FactoryBot.define do
  factory :comment do
    body { Faker::Book.title }
  end

  trait :article do
    type 'ArticleComment'
  end
end

のようにtraitを使って定義することで、

create :comment, :article

とすることで、typeにarticleが指定されたCommentインスタンスを作成することができますが、
クラスはArticleCommentクラスではなく、Commentクラスになっています。

この場合、ArticleCommentに定義されたインスタンスメソッドのテストを行うことができません。

なので、

FactoryBot.define do
  factory :comment do
    body { Faker::Book.title }
  end

  trait :article do
    type 'ArticleComment'
      initialize_with do
        klass = type.constantize
        klass.new(attributes)
      end
  end
end

このようにinitialize_with メソッドを使うことで、
ArticleCommentクラスのインスタンスを生成することができます。



参考にさせていただいた記事
STIを利用している場合のFactoryBotのfactory定義について - indilog