如何在Elixir Plug测试中设置POST请求的正文?



使用Plug.Test.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

使用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"

我还尝试根据文档传递字符串并设置内容类型标头。

在传递到conn之前使用Poison.encode!将主体转换为二进制文件:

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

最新更新