hanami new コマンドは application_layout_spec.rb を自動生成し、レイアウトクラスの単体テストのボイラープレートを用意してくれる。しかし実はこれは private API に依存しているとのこと。

Rendering a partial template from application layout breaks view rendering in unit test environment · Issue #129 · hanami/view (https://github.com/hanami/view/issues/129)

具体的なエラー発生ケースはこう。まずこれが自動生成されたテストケース。もちろんこれは初めはパスする。

require "spec_helper"

RSpec.describe Web::Views::ApplicationLayout, type: :view do
  let(:layout)   { Web::Views::ApplicationLayout.new({ format: :html }, "contents") }
  let(:rendered) { layout.render }

  it 'contains application name' do
    expect(rendered).to include('Web')
  end
end

で、templates/application.html.erbに部分テンプレートの呼び出しを追記する。

  <!DOCTYPE html>
  <html>
    <head>
      <title>Web</title>
      <%= favicon %>
    </head>
    <body>
+     <%= render partial: 'shared/navbar' %>
      <%= yield %>
    </body>
  </html>

すると、テストファイルからの呼び出しがうまくいかず、失敗する。

Failure/Error: let(:rendered) { layout.render }

NoMethodError:
  undefined method `template' for Class:Class

開発画面では問題ないのに、テストだけが失敗する。慣れないフレームワークで何が原因なのかもわからず戸惑ってしまっていたが、結論としては プライベートAPIはテストするべきでない という基本事項に立ち返ることとなった。

当該のテストは消してしまい、代わりにフィーチャースペックで簡単な検証を書いた。