27

何が間違っているのかわかりませんが、リダイレクトをテストしようとするたびに、「@request must be an 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)>'

Capybara (1.1.2) と Rails 3.2 で RSpec-rails (2.9.0) を使用しています。誰かがなぜこれが起こっているのか説明できれば幸いです。そのような方法で期待を使用できないのはなぜですか?

4

5 に答える 5

42

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

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

current_path.should == new_user_path
page.should have_selector('div#erro_div')
于 2012-06-08T20:42:14.487 に答える
11

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

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

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

于 2012-06-09T18:55:53.373 に答える
7

ここに私が見つけたハックな解決策があります

# 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
于 2015-08-05T11:35:28.960 に答える