LoginSignup
1
1

More than 5 years have passed since last update.

FactoryGirlに新しいシンタックスを追加する

Posted at

本来やりたかったこと

DB分割前提のテストを書きたいので、FactoryGirlを拡張して、シャード指定できるようにしたい。
ちなみに分割はOctopusを利用した水平分割です。

FactoryGirlにシンタックスを追加する方法

概要

方法は色々ありそうですが、今回は、FactoryGirl::StrategySyntaxMethodRegistrarを利用します。
非公開APIっぽいのでメンテナーにはあまりいい顔されないかもしれません。
例として、テストコードを書いてるときに🍣が食べたくなった時を想定してcreate_sushiを追加します

コード例

spec/support/factory_girl_ext.rb
class SushiSyntaxRegistrar < FactoryGirl::StrategySyntaxMethodRegistrar
  def define_strategy_methods
    define_sushi
  end

  private

  def define_sushi
    strategy_name = @strategy_name

    define_syntax_method("#{strategy_name}_sushi") do
      Rails.logger.debug "🍣"
    end
  end
end

sushi_create_syntax_registrar = SushiSyntaxRegistrar.new(:create)
sushi_create_syntax_registrar.define_strategy_methods
spec/models/sushi.rb
RSpec.describe Sushi, type: :model do
  it "looks like 🍣" do
    expect(create_sushi).to be true
  end
end

テストを実行するとログに🍣が表示されています。やったね!

ちょっとだけ解説

  • デフォルトだとspec/support/配下は読まなかった気がするので、spec_helper.rb辺りでrequireしてあげてください
  • FactoryGirl::StrategySyntaxMethodRegistrar#initializeの引数は定義するシンタックスに利用されます。
    • 今は:createを引数にしてcreate_sushiを定義していますが、:buildを渡せば build_sushiも定義することが出来ます
  • FactoryGirl::StrategySyntaxMethodRegistrar#define_syntax_methodは、FactoryGirl::Syntax::Methodsに対してメソッドを追加するメソッドです。もし、すでに定義されてしまっている場合はModule#undef_methodしてしまうので、createを定義すると後勝ちでcreateが全て🍣メソッド化します :fearful:

本来やりたかったことの解決

  • 要するに便利なdefine_methodを呼んでいるようなものなので、上のdefine_sushiのように今回は以下のようなコードを書きました
  • 以下を実行すると、create_with_shard :model_name, :shard1 のようなシンタックスが生まれます
def define_singular_strategy_method_with_shard
  strategy_name = @strategy_name

  define_syntax_method("#{strategy_name}_with_shard") do |name, shard, *traits_and_overrides, &block|
    Octopus.using(shard) do
      FactoryGirl::FactoryRunner.new(name, strategy_name, traits_and_overrides).run(&block)
    end
  end
end

まとめ

  • FactoryGirlにsyntaxを追加する方法でした。
1
1
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
1
1