末尾で他のaction(do_create
、仮)を呼び出すcreate
のテストを書いたとき、
it 'do_createが呼ばれる' do
expect(controller).to receive(:do_create).and_return(true)
post :create, params
end
といつも通り書いたところ、下記のようなエラーが出た。
ActionView::MissingTemplate:
Missing template path/to/create, ..., application/create with {:locale=>[:en, :ja], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :slim, :coffee, :haml, :jbuilder]}. Searched in:
要はrenderするときに指定されたテンプレートファイルが見つからないよ、というエラー
原因
create
においてはdo_create
がメインの処理で、その中でリダイレクトしたりエラーを出したりあるいはrenderしたりする。
つまり、do_create
をスタブ化してしまったらこのアクションは存在しない自身のviewファイルを探しにいってしまいエラーが出てしまうということだと思われる。
対策
まず、仮にテンプレートファイルを置いてみた。
$ touch path/to/create.html
はい、これだけで問題なく通りました。
しかしこれではコミットできないので、do_create
のスタブの中身を適当に存在するテンプレートを呼ぶrenderに変えてみた。
expect(controller).to receive(:do_create) { render_template :edit }
post :create, params
しかしこれでは駄目。メソッドの最後にrenderを置いているのになぜ?恐らく書き方が悪いんだと思うがどこが悪いのかわからない。
そこでエラーを投げるようにしてみた。
expect(controller).to receive(:do_create).and_raise(DummyError)
expect { post :create, params }.to raise_error(DummyError)
DummyErrorクラスは実際のエラーと区別するためにspecファイルの中で定義したエラークラス。これで一応動いた。バッドプラクティス感がすごいが、メモとして残しておきます。