Dry::AutoInjectでinitializeをオーバーライドした時にArgumentError: wrong number of arguments (given 1, expected 0)になる
結論
- Dry::AutoInjectでincludeしているクラスにネストしたクラスが別ファイルで存在しているとダメだった
- とりあえずネストしたクラスの構成を変える or includeしているクラスの中にクラスを書く
状況
- クラスFooServiceでDry::AutoInjectを使って、ContainerからDIをしている
- クラスFooServiceのinitializeをオーバーライドして、DI以外の処理を挿入していた
- クラスFooServiceにネストしたクラスを別で定義している(コードの良し悪しは置いといて下記のようなイメージ)
# foo_service.rb class FooService Import = Dry::AutoInject(MyContainer) include Import[hoge_repository: 'repositories.hoge'] def initialize(hoge:, **args) super(**args) @hoge = hoge ... end def call bar = Bar.new bar.fuga ... end end # foo_service/bar.rb class FooService class Bar def fuga # FooServiceで使うなんかの処理とか end end end
症状
この状態で次のようにinitializeが実行されるとでエラーが発生する
# foo_service_test.rb class FooServiceTest < ActiveSupport::TestCase test 'なんかのテスト' do hoge = "hoge" hoge_repository_mock = Minitest::Mock.new service = FooService.new(hoge: hoge, hoge_repository: hoge_repository_mock) end end ... # 実行結果 ArgumentError: wrong number of arguments (given 1, expected 0) /Users/xxxxxx/.rbenv/versions/**/lib/ruby/gems/**/gems/dry-auto_inject-1.0.0/lib/dry/auto_inject/strategies/kwargs.rb:45:in `block (2 levels) in define_initialize_with_keywords' /Users/xxxxxx/**/foo_service.rb:*:in `initialize' /Users/xxxxxx/.rbenv/versions/**/lib/ruby/gems/**/gems/dry-auto_inject-1.0.0/lib/dry/auto_inject/strategies/kwargs.rb:19:in `new' /Users/xxxxxx/.rbenv/versions/**/lib/ruby/gems/**/gems/dry-auto_inject-1.0.0/lib/dry/auto_inject/strategies/kwargs.rb:19:in `block (2 levels) in define_new' /Users/xxxxxx/**/foo_service_test.rb:**:in `block in <class:FooServiceTest>'
オーバーライドしてもsuper()に、DIする引数を渡せばオーバーライドできるはずなのに、super()で引数を受け付けていないという状態になる
対策
- クラスの構成を変える
# foo_service/bar.rb class Bar def fuga # FooServiceで使うなんかの処理とか end end
- ネスト元のクラスに定義する
# foo_service.rb class FooService Import = Dry::AutoInject(MyContainer) include Import[hoge_repository: 'repositories.hoge'] def initialize(hoge:, **args) super(**args) @hoge = hoge ... end class Bar def fuga end end end
他のクラスでオーバーライドできていたのに、これに該当するクラスでなぜかinitializeのオーバーライドが効かず、めちゃくちゃ沼った。 ちゃんとコードを追った上でコントリビュートするべきなのだろうけど、時間の捻出がなかなかできず... 一旦書き置き。