2017-07-17 63 views
1

使用Plug.Test.conn,設置請求主體似乎不起作用。如何在Elixir Plug測試中設置POST請求的主體?

這裏的插頭:

defmodule MyPlug do 
    import Plug.Conn 

    def init(_), do: nil 

    def call(conn, _) do 
    {:ok, body, _conn} = read_body(conn) 
    send_resp(conn, 200, "body: #{body}") 
    end 
end 

使用curl

$ curl -X POST -d foo=bar http://localhost:4000/ 
body: foo=bar 

使用Plug.Test

defmodule MyTest do 
    use ExUnit.Case, async: false 
    use Plug.Test 

    test "POST request" do 
    conn = conn(:post, "/", %{foo: "bar"}) 
      |> MyPlug.call(%{}) 
    assert conn.resp_body == "body: foo=bar" 
    end 
end 

失敗:

1) test POST request (MyPlugTest) 
    test/my_plug_test.exs:28 
    Assertion with == failed 
    code: conn.resp_body() == "body: foo=bar" 
    left: "body: " 
    right: "body: foo=bar" 

我也試過傳遞一個字符串並按照docs設置內容類型標題。

回答

3

使用Poison.encode!的身體轉換爲二進制傳遞給conn前:

defmodule MyPlug do 
    import Plug.Conn 

    def init(_), do: nil 

    def call(conn, _) do 
    {:ok, body, _conn} = read_body(conn) 
    send_resp(conn, 200, "body: #{body}") 
    end 
end 

defmodule MyTest do 
    use ExUnit.Case 
    use Plug.Test 

    test "POST request" do 
    conn = conn(:post, "/", Poison.encode!(%{foo: "bar"})) 
      |> MyPlug.call(%{}) 
    assert conn.resp_body == ~S(body: {"foo":"bar"}) 
    end 
end 

然而Plug.Conn.read_body只能使用一次,之後,它丟棄該數據。所以,你可能需要使用Plug.Parsers解析在管道更早體:

plug Plug.Parsers, 
    parsers: [:urlencoded, :multipart, :json], 
    pass: ["*/*"], 
    json_decoder: Poison 

解析後,身體可作爲conn.body_params併合併到conn.params