elixir - 我是否必须做任何事情才能使 Plugs 在测试环境(Elixir / Phoenix)中工作?
问题描述
我有一个基本应用程序并尝试在我的控制器上使用插件。如果请求正文没有“url”参数,它基本上应该返回 400。当我从邮递员发送请求时它工作正常,但它似乎不适用于我的测试。
我是否必须做任何事情才能使其在测试环境中也能正常工作?
plug :check_url_existence when action in [:create]
def create(conn, link_params) do
with {:ok, %Link{} = link} <- Links.create_link(link_params) do
conn
|> put_status(:created)
|> put_resp_header("location", Routes.link_path(conn, :show, link))
|> render("show.json", link: link)
end
end
defp check_url_existence(conn, _) do
if is_nil(conn.params["url"]) do
conn
|> put_status(:bad_request)
|> put_view(ShortyWeb.ErrorView)
|> render("400.json")
end
conn
end
测试:
test "returns an error without a url", %{ conn: conn } do
response =
conn
|> post("/shorten", %{})
|> json_response(400)
assert response["errors"] != %{}
end
结果:
1) test shortcode generation returns an error without a url (ShortyWeb.LinkControllerTest)
test/shorty_web/controllers/link_controller_test.exs:58
** (RuntimeError) expected response with status 400, got: 422, with body:
{"errors":{"url":["can't be blank"]}}
code: |> json_response(400)
stacktrace:
(phoenix) lib/phoenix/test/conn_test.ex:373: Phoenix.ConnTest.response/2
(phoenix) lib/phoenix/test/conn_test.ex:419: Phoenix.ConnTest.json_response/2
test/shorty_web/controllers/link_controller_test.exs:62: (test)
邮递员结果: https ://prnt.sc/qdy2bo
解决方案
您的 plug 函数的编写方式是无论如何conn
都将返回未更改的内容。
您需要将最后一行移动到一个else
块中。此外,该if
块可能需要调用halt/1
.
否则,它将继续使用该create
函数并尝试创建链接,但由于验证问题(url 为空白),它将像现在一样失败并返回 422。
你应该将你的插件重写为类似的东西
defp check_url_existence(conn, _) do
if is_nil(conn.params["url"]) do
conn
|> put_status(:bad_request)
|> put_view(ShortyWeb.ErrorView)
|> render("400.json")
|> halt()
else
conn
end
end
您还应该考虑按照其他人的建议进行操作,而不必担心解析参数。422 似乎是一个有效的响应代码。
如果你想坚持使用 400 处理程序,因为你试图在这里实现,这里有另一种编写它的方法。
defp check_url_existence(%{params: %{"url" => url}} = conn) when not is_nil(url), do: conn
defp check_url_existence(conn) do
conn
|> put_status(:bad_request)
|> put_view(ShortyWeb.ErrorView)
|> render("400.json")
|> halt()
end
为了直接回答您的问题,conn 测试助手会遍历路由器代码,因此应该应用插件。
在某些极端情况下,当您实现自己的帮助程序时,您需要手动调用某些插件函数,但这些可能超出了问题的范围。
推荐阅读
- php - 如何制作返回与需要在其中查找值的数组关联的键名的函数?
- node.js - heroku DATABASE_URL 在 nodejs 应用程序中未定义
- javascript - Javascript:如何从原型管理转移到类的概念?
- ios - 如何在 react-native 项目中保存 info.plist 中的更改
- amazon-web-services - 是否可以将 VM 快照映像从 GCP 共享到 AWS,反之亦然?
- qemu - QEMU 上的 Microblaze 不产生串行输出
- git - 远程删除文件夹但不是本地git
- excel - 如果满足某些条件并将结果输入另一个工作簿,则计算行数
- c# - C# PInvoke 我无法使用 CreateFile 打开卷
- python - 运行从不同位置导入另一个 python 脚本的 Python 脚本