テストの表示

ビューとしてのオブジェクトのメリットの1つは、ユニットテストが可能なことです。特定のプレゼンテーションロジックが正しく動作するか、レンダリングされたマークアップの内容をアサートするかを理解できます。

次の例では、RSpecをテストダブルの簡潔な構文に使用します。

# spec/web/views/books/show_spec.rb
require 'spec_helper'
require_relative '../../../../apps/web/views/books/show'

RSpec.describe Web::Views::Books::Show do
  let(:exposures) { Hash[book: double('book', price: 1.00), current_user: user] }
  let(:template)  { Hanami::View::Template.new('apps/web/templates/books/show.html.erb') }
  let(:view)      { Web::Views::Home::Another.new(template, exposures) }
  let(:rendered)  { view.render }
  let(:user)      { double('user', admin?: false) }

  describe "price" do
    it "returns formatted price" do
      expect(view.formatted_price).to eq "$1.00"
    end
  end

  describe "edit link" do
    it "doesn't show it by default" do
      expect(rendered).to_not match %(edit)
    end

    context "when admin" do
      let(:user) { double('user', admin?: true) }

      it "shows it" do
        expect(rendered).to match %(edit)
      end
    end
  end
end

上記のテストコードの最初の部分は、書籍の書式設定価格についてです。このプレゼンテーションロジックは、の戻り値をアサートすることによって検証されview.formatted_priceます。

残りのコードはアクセス許可関連のロジックです。編集リンクは、現在のユーザーが管理者である場合にのみレンダリングする必要があります。これは、テンプレートの出力を調べることによってテストされます。

ビューのメソッドを介して直接的に、またはレンダリングされたマークアップを介して間接的にプレゼンテーションロジックをアサートすることは、2つの均等な方法です。

対応するプロダクションコードを見てみましょう。

# apps/web/views/books/show.rb
module Web::Views::Books
  class Show
    include Web::View

    def formatted_price
      "$#{ format_number book.price }"
    end

    def edit_link
      if can_edit_book?
        link_to "Edit", routes.edit_book_path(id: book.id)
      end
    end

    private

    def can_edit_book?
      current_user.admin?
    end
  end
end