ActiveDecorator で URL 系ヘルパーを使っているとき,テストで NoMethodError が出ることがある。
どうすればよいか。
本記事は,私が Qiita で質問
[Q&A] URL ヘルパーを含む ActiveDecorator のメソッドがテストで使えない - Qiita
を立てて,回答として @uasi さんにご教示いただいた解決方法を記事にしたものです。@uasi さん,ありがとうございました。
問題
ActiveDecorator のデコレーターメソッドに URL ヘルパーやパスヘルパーを使うことがよくある。
module ItemDecorator
def path
item_path(self)
end
end
こうしておくと,@item に Item のインスタンスが入っていたら
@item.path
で /items/1 のようなパスが得られる1。
しかし,これをテストコードで使うと,中で使われている item_path が NoMethodError になる。
これに対処する方法はあったが,active_decorator 1.5.0(2025-09-29 リリース)で使えなくなったので,既述の質問を立てた次第。
解決方法
ここでは,@uasi さんに教えていただいた,active_decorator 1.5.0 以降でも使える方法だけを記載する。
(私はテストに RSpec でなく Minitest を使っているので,Minitest が前提2)
test_helper.rb に以下を追記する。これだけ。
require "active_decorator/view_context"
ActiveDecorator::ViewContext.after_reset prepend: true do
ActiveDecorator::ViewContext.push Rails.application.routes.url_helpers
end
なぜこうする必要があるのか,については件の質問の回答をご覧ください。
active_decorator 側で,デフォルトで url_helpers が使えるようになっているか,あるいは上記コードよりもっとシンプルな方法で Rails.application.routes.url_helpers が追加できるようになっているといいのだけれど……。
-
@itemはデコレートされている必要がある。なお,こんな単純なパスでデコレーターを使うメリットはないが,もっと実用的な例は Rails:ネストしたルーティングのパスヘルパーが長えよ を参照されたい。 ↩ -
RSpec も同じようにできるのだと思うが,使ったことがないので分からない。 ↩