2016-09-13 3 views
0

ログイン要件プラグは、this example by Thoughtbotに記載されているものとよく似ています。私は、ユーザーがリダイレクトされたときにフラッシュ通知を追加したい。これはブラウザでは動作しますが、単独でテストするときには動作しません。カスタムプラグをユニットテストするときにセッションとフラッシュにアクセスする

プラグ:

# In webs/plugs/require_login.ex 
defmodule MyApp.Plugs.RequireLogin do 
    import Plug.Conn 

    def init(opts), do: opts 
    if false # real user authentication omitted 
     conn 
    else 
     conn 
     |> Phoenix.Controller.put_flash(:error, "Login required.") 
     |> Phoenix.Controller.redirect(to: "/") 
     |> halt 
    end 
    end 
end 

このために使用される試験:

defmodule MyApp.Plugs.RequireLoginTest do 
    use MyApp.ConnCase 

    test "user is redirected when authentication fails" do 
    conn = conn |> MyApp.Plugs.RequireLogin.call(%{}) 

    assert Phoenix.Controller.get_flash(conn, :error) == "Login required." 
    assert redirected_to(conn) == "/" 
    end 
end 

Iが得るエラーメッセージがある:

(例外ArgumentError)フラッシュフェッチされていない、fetch_flashを呼び出します/ 2

プラグモジュールでエラーが発生しましたが、そこにput_session行をコメントアウトすると、エラーがテストファイルに移動します。

セッションストアがlib/my_app/endpoint.exに設定されていることを理解していますが、この設定を再利用してプラグをユニットテストできるようにするにはどうすればよいですか?

はここでプラグをルータに引っ掛けられる方法は次のとおりです。

# web/router.ex 
pipeline :browser do 
    # the Phoenix default 
end 

scope "/", MyApp do 
    pipe_through [:browser, MyApp.Plugs.RequireLogin] 
    resource "/protected", MyController, only: [:index] 
end 

答えて

1

bypass_throughを使用して解決できました。私はリクエストを「発射」しなかった。 Phoenix.ConnTest.get/3となり、プラグ・パイプラインが呼び出されません。 get/3を追加するとすぐに、フラッシュハッシュが利用可能になりました。

defmodule MyApp.Plugs.RequireLoginTest do 
    use MyApp.ConnCase 

    test "user is redirected when authentication fails", %{conn: conn} do 
    conn = conn 
      |> with_pipeline 
      |> MyApp.Plugs.RequireLogin.call(%{}) 

    assert Phoenix.Controller.get_flash(conn, :error) == "Login required." 
    assert redirected_to(conn) == "/" 
    end 

    defp with_pipeline(conn) do 
    conn 
    |> bypass_through(MyApp.Router, [:browser]) 
    |> get("/protected-uri") # any uri, bypass_through ignores the router rules 
    end 
end 
0

編集
私の心に来る最初の事はあなたのテストでのparamが欠落しているです。

あなたCONNは、おそらくどこかConnCaseで生成されます。

setup tags do 
    ... 

    {:ok, conn: Phoenix.ConnTest.build_conn()} 
end 

そして、あなたのテストは次のようになります必要があります。このCONNを使用できるように

test "user is redirected when authentication fails", %{conn: conn} do 



第二のものは、そこには、要求がテスト中(ポストなど/ GET)ではありませんし、あなたのconnはおそらく:browserパイプラインを通過しないということです。

+1

ありがとうございます@amatalai。私のプラグインは、単体テストから実行されたときではなく、ブラウザセッションで問題なく動作しています。私はそれを明確にするために私の質問を更新しました。 – carp

+0

@ carpも私の答えを更新しました – amatalai

+0

あなたの答えは、テストでパイプラインの使用を強制する方法を掘り起こしました。私は 'bypass_through/3'を見つけました - 下の私の答えを見てください。ありがとう! – carp

関連する問題