web-dev-qa-db-ja.com

redirect_to:backをテストするRspec

Rspecで_redirect_to :back_をテストするにはどうすればよいですか?

私は得る

_ActionController::RedirectBackError_:
このアクションへのリクエストで_HTTP_REFERER_が設定されていないため、_redirect_to :back_を正常に呼び出すことができませんでした。これがテストの場合は、必ず_request.env["HTTP_REFERER"]_を指定してください。

テストで_HTTP_REFERER_を設定するにはどうすればよいですか?

61
Cyrus

RSpecを使用すると、beforeブロックにリファラーを設定できます。テストでリファラーを直接設定しようとすると、どこに配置しても機能しているようには見えませんでしたが、beforeブロックがトリックを行います。

describe BackController < ApplicationController do
  before(:each) do
    request.env["HTTP_REFERER"] = "where_i_came_from"
  end

  describe "GET /goback" do
    it "redirects back to the referring page" do
      get 'goback'
      response.should redirect_to "where_i_came_from"
    end
  end
end
112
joshuarh

Railsガイド から、新しいリクエストスタイルでリクエストをリクエストする場合:

describe BackController < ApplicationController do
  describe "GET /goback" do
    it "redirects back to the referring page" do
      get :show, 
        params: { id: 12 },
        headers: { "HTTP_REFERER" => "http://example.com/home" }
      expect(response).to redirect_to("http://example.com/home")
    end
  end
end
3
ivanxuu

誰かがこれにつまずいてrequest仕様を使用している場合、作成するリクエストにヘッダーを明示的に設定する必要があります。テストリクエストの形式は、使用しているRSpecのバージョンと、位置引数の代わりにキーワード引数を使用できるかどうかによって異なります。

let(:headers){ { "HTTP_REFERER" => "/widgets" } }

it "redirects back to widgets" do 
  post "/widgets", params: {}, headers: headers # keyword (better)
  post "/widgets", {}, headers                  # positional

  expect(response).to redirect_to(widgets_path)
end

https://relishapp.com/rspec/rspec-Rails/docs/request-specs/request-spec

3
sp89

私見受け入れられた答えは少しハックです。より良い代替方法は、HTTP_REFERERをアプリケーションの実際のURLに設定してから、リダイレクトされることです。

describe BackController, type: :controller do
  before(:each) do
    request.env['HTTP_REFERER'] = root_url
  end

  it 'redirects back' do
    get :whatever
    response.should redirect_to :back
  end
end
  • ランダムな文字列定数へのリダイレクトは、偶然に動作しているように感じます
  • Rspecの組み込み機能を利用して、必要なものを正確に表現します。
  • マジックストリング値を導入して繰り返しません

Rspecの新しいバージョンでは、代わりに期待値を使用できます。

expect(response).to redirect_to :back
1
ndnenkov

統合テストの:backリンクのテストに関しては、最初にリンクとして使用される可能性が低いと思われるデッドエンドページにアクセスし、次にテスト中のページにアクセスします。だから私のコードは次のようになります

   before(:each) do
       visit deadend_path
       visit testpage_path
    end
    it "testpage Page should have a Back button going :back" do
      response.should have_selector("a",:href => deadend_path,
                                        :content => "Back")
    end

ただし、これには、リンクが実際にdeadend_pathへのリンクである場合、テストが誤ってパスするという問題があります。

1
Obromios