10

Rails 3レイアウトでロジックをテストする最良の方法は何ですか?

例:ユーザーが私のサイトにサインインしたときに、オンボーディングプロセスを完了していない場合は、すべてのページの画面上部にアラートを表示します。このロジックは、アプリケーションレイアウトに配置されました。ログインしているユーザーの特定のキーを確認するだけです。キーが存在しない場合は、アラートを表示します。キーが表示されるとすぐに(つまり、オンボーディングが完了したことを意味します)、アラートは表示されません。

現在、ビューテストでこれを実行しようとしていますがActionView::Template::Error: undefined method、アプリケーションレイアウトを含めることで、nil:NilClass`エラーに対してあらゆる種類の認証を取得しており、この機能をテストできないようです。

何らかの理由で開発者の1人が誤ってこの機能を壊した場合(オンボーディングで表示されるビューが完全ではない場合)、ビルド直後に知る必要があるため、これをテスト中であることを確認する必要があります。

レイアウトでテストしようとしているコードは次のようになります。

<% if user_signed_in? %>
    <% unless current_user.has_completed_onboarding? %>
      <div class="alert">
        You cannot accept payments from your clients until you set up your payment gateway.
        <%= link_to "Set up your", payment_gateway_path %> payment gateway. Its quick, we promise. :)
      </div>
    <% end %>
<% end %>

オンボーディングの詳細が提供されていない場合はこのメッセージが表示され、提供されている場合はこのメッセージを表示しないようにしたいと思います。

4

2 に答える 2

14

他のビューと同じようにレイアウトをテストできます。にファイルを作成し(必要に応じて置き換えます)、application.html.erb_spec.rbそのファイルに通常どおりに仕様を記述します。例:erbhamlspec/views/layouts/

require 'spec_helper'

describe 'layouts/application' do

  context 'signed-in user' do

    before { view.stub(:user_signed_in?) { true } }

    context 'completed onboarding' do

      before do
        user = double('user')
        user.stub(:has_completed_onboarding?) { false }
        assign(:current_user, user)
      end

      it "should display alert" do
        render
        rendered.should have_selector('.alert')
      end

    end

    ...

  end

  context 'signed-out user' do
    ...
  end

  ...

end

私は自分のアプリの1つでこれを行っていますが、問題なく動作するので、なぜそれがあなたのケースでも動作しないのかわかりません。

于 2012-11-10T15:26:14.003 に答える
2

発生したエラーは、ビューのメソッド呼び出しActionView::Template::Error: undefined method authenticate for nil:NilClassが原因で発生します。@shioyamaがコードで示したように、テストでメソッドをスタブ化することでuser_signed_in?これを処理できます。user_signed_in?

次のコードは、ビュー内のステートメントを実行する場合と実行しない場合に、メソッドをスタブしてuser_signed_in?返す方法を示しています。 trueiffalseview.stub(:user_signed_in?).and_return(true)

于 2012-12-03T12:14:03.713 に答える