web-dev-qa-db-ja.com

RspecとCapybaraでリダイレクトをテストする方法

何が問題なのかわかりませんが、リダイレクトをテストしようとするたびに、「@ requestはActionDispatch :: Requestでなければなりません」というエラーが表示されます。

context "as non-signed in user" do
  it "should redirect to the login page" do
    expect { visit admin_account_url(account, Host: get_Host(account)) }.to redirect_to(signin_path)
  end
end
1) AdminAccountPages Admin::Accounts#show as non-signed in user should redirect to the login page
     Failure/Error: expect { visit admin_account_url(account, Host: get_Host(account)) }.to redirect_to(signin_path)
     ArgumentError:
       @request must be an ActionDispatch::Request
     # ./spec/requests/admin_account_pages_spec.rb:16:in `block (4 levels) in <top (required)>'

私はRSpec-Rails(2.9.0)をカピバラ(1.1.2)とRails 3.2。私はこのように期待を使用していますか?

22
Mohamad

CapybaraはRails固有のソリューションではないため、Railsのレンダリングロジックについて何も知りません。

Capybaraは、統合テスト用に特別に意図されています。これは、エンドユーザーがブラウザーと対話する観点からテストを本質的に実行することです。これらのテストでは、エンドユーザーがアプリケーションの深いところを見ることはできないため、テンプレートをアサートするべきではありません。代わりにテストする必要があるのは、アクションが正しいパスに到達することです。

current_path.should == new_user_path
page.should have_selector('div#erro_div')
39
Sagiv Ofek

あなたはこのようにそれを行うことができます:

expect(current_path).to eql(new_app_user_registration_path)
16
The Whiz of Oz

Rスペック3:

現在のパスをテストする最も簡単な方法は次のとおりです。

expect(page).to have_current_path('/login?status=invalid_token')

_have_current_path_には、このアプローチに勝る利点があります。

expect(current_path).to eq('/login')

クエリパラメータを含めることができるからです。

13
Zippie

エラーメッセージ@request must be an ActionDispatch::Requestは、rspec-Railsマッチャーredirect_to(Rails assert_redirected_toに委任)がRailsでの使用を期待していることを示しています。機能テスト(ActionController::TestCaseを混在させる必要があります)。あなたが投稿したコードは、rspec-Railsリクエスト仕様のように見えます。そのため、redirect_toは使用できません。

リダイレクトのチェックは、rspec-Rails要求仕様ではサポートされていませんが、Rails統合テストではサポートされています。

リダイレクトがどのように行われたか(それが301応答であり、一部のJavaScriptではない)を明示的に確認する必要があるかどうかは、完全にあなた次第です。

11
Art Shayderov

これが私が見つけたハッキーな解決策です

# spec/features/user_confirmation_feature.rb

feature 'User confirmation' do
  scenario 'provide confirmation and redirect' do
    visit "/users/123/confirm"

    expect(page).to have_content('Please enter the confirmation code')
    find("input[id$='confirmation_code']").set '1234'

    do_not_follow_redirect do
      click_button('Verify')
      expect(page.driver.status_code).to eq(302)
      expect(page.driver.browser.last_response['Location']).to match(/\/en\//[^\/]+\/edit$/)
    end
  end

  protected

  # Capybara won't follow redirects
  def do_not_follow_redirect &block
    begin
      options = page.driver.instance_variable_get(:@options)
      prev_value = options[:follow_redirects]
      options[:follow_redirects] = false

      yield
    ensure
      options[:follow_redirects] = prev_value
    end
  end
end
7
Max