Reputation: 9712
Using Plug.Test.conn
, setting the request body doesn't seem to work.
Here's the plug:
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
Using curl
:
$ curl -X POST -d foo=bar http://localhost:4000/
body: foo=bar
Using 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
Failure:
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"
I've also tried passing a string and setting content-type header as per docs.
Upvotes: 3
Views: 2413
Reputation: 4885
Use Poison.encode!
to convert the body to a binary before passing to 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
However Plug.Conn.read_body
can only be used once, after that it discards the data. So you may want to use Plug.Parsers
to parse the body earlier in the pipeline:
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
After parsing, the body is available as in conn.body_params
and merged into conn.params
.
Upvotes: 6