我正在尝试测试端点是否在无效JSON上返回400。如果我做这样的事情:
response = conn
|> put_req_header("content-type", "application/json")
|> post(Routes.convert_path(conn, :convert), "invalid JSON")
我将得到一个Jason.DecodeError
,因为它正在尝试对我的字符串进行编码。我怎样才能不对它进行编码?查看文档似乎无法完成:
post(conn, path_or_action, params_or_body \\ nil)
还有另一种方法可以完成我想完成的事情吗?
test/github_omg_web/controllers/convert_controller_test.exs:36
** (Plug.Parsers.ParseError) malformed request, a Jason.DecodeError exception was raised with message "unexpected byte at position 0: 0x61 ('a')"
code: |> post(Routes.convert_path(conn, :convert), "asdf")
stacktrace:
(plug) lib/plug/parsers/json.ex:97: Plug.Parsers.JSON.decode/2
(plug) lib/plug/parsers.ex:271: Plug.Parsers.reduce/7
(github_omg) lib/github_omg_web/endpoint.ex:1: GithubOmgWeb.Endpoint.plug_builder_call/2
(github_omg) lib/github_omg_web/endpoint.ex:1: GithubOmgWeb.Endpoint.call/2
(phoenix) lib/phoenix/test/conn_test.ex:235: Phoenix.ConnTest.dispatch/5
test/github_omg_web/controllers/convert_controller_test.exs:40: (test)
答案 0 :(得分:1)
我创建了一个最小的示例,以确保我们在同一页面上:
mix phx.new github_omg
mix ecto.create
mix phx.gen.json Accounts User users name:string
mix ecto.migrate
iex -S mix phx.server
要复制,您可以一步一步粘贴命令,然后按照说明进行操作,例如(phx.gen.json
指示将resources "/users", UserController, except: [:new, :edit]
中的scope "/api"
添加到lib/github_omg_web/router.ex
中的github_omg
中。
这将创建一个具有相同名称Accounts
,名为localhost:4000/api/users
的上下文和名为curl
的api端点的新项目
让我们用curl --write-out '%{http_code}' --silent -X POST -H "Content-Type: application/json" --data "Invalid JSON" --output /dev/null localhost:4000/api/users
执行格式错误的请求:
--silent
我正在使用--output /dev/null
和--write-out '%{http_code}
隐藏响应正文。在开发模式下,它将输出整个Phoenix错误网页,并使输出混乱。 -H
显示http状态,--data
添加标头,400
是我们发送的无效JSON。
输出将是:
[info] POST /api/users
[debug] ** (Plug.Parsers.ParseError) malformed request, a Jason.DecodeError exception was raised with message "unexpected byte at position 0: 0x49 ('I')"
因此Phoenix可以正确输出400。
在Phoenix控制台中,我们将看到:
ParseError
因此,看起来Phoenix会自动将Plug.Exception
转换为400。实际上,这并不是那么神奇:)
Phoenix使用defexception
协议计算错误。基本上,您可以抛出任何您喜欢的异常。 plug_status
宏允许您在异常内附加自定义字段。 Phoenix寻找一个名为Plug.Parser
的字段。 ParseError
定义api
返回400。
回到原始问题:
您误读了堆栈错误。测试框架不会尝试对有效载荷进行编码。这是您的应用尝试对其进行解码(并且失败)。您可以向后读取堆栈跟踪:
这意味着您有两个选择:
assert_raise Plug.Parsers.ParseError, fn ->
conn
|> put_req_header("content-type", "application/json")
|> post(Routes.convert_path(conn, :convert), "invalid JSON")
end
管道弄乱了),而不是检查400,则可以检查您的应用是否出现正确的错误:/usr/local/bin/ea-php56 /home/username/domain_path/path/to/cron/script
仅在显式设置的情况下,才显式测试conn中的400。