elixir - 早期返回不适用于 elixir/phoenix 的集成测试
问题描述
我对 Elixir 完全陌生,但是在使用 Node 时,我们会进行很多提前返回,但是在我的集成测试中让类似提前返回的代码工作时遇到了一些问题。这是我的问题:
我的控制器中有这个方法,它接收一个 JSON 作为参数,我需要验证 JSON 是否包含一些属性(键和类型),如果它不包含我想向客户端发送错误而不需要执行其余的方法。这在我使用 Insomnia 或 Postman 发出请求时非常有效,但在我的集成测试中不起作用。即使条件是假的,条件下面的代码也会执行。
这是我的方法:
def create(conn, body) do
if !PayeeContext.check_for_required_fields(body), do: conn
|> send_resp(400, "Please provide Key and Type parameters")
%{"key" => key} = body
%{"type" => type} = body
validation_func = PayeeContext.validation_map(type)
case validation_func.(key) do
{:ok, _} ->
conn |> send_resp(200, "Request created successfully")
{:error, message} -> conn |> send_resp(400, message)
end
end
这是我的测试
test "returns 400 if Key prop is missing", %{conn: conn} do
params = %{
key: "44187221816",
account: %{
account_type: "checking_account",
account_number: "00028363-6",
branch: "0001"
},
owner: %{
name: "Eve Montalvão"
}
}
response = conn |> post(Routes.payee_path(conn, :create, params))
assert response.status == 400
end
和我的 PayeeContext.check_for_required_fields
def check_for_required_fields(fields) do
Enum.all?(@required_fields, fn field -> Map.has_key?(fields, field) end)
end
我究竟做错了什么?
解决方案
Elixir 中的 if 语句很少见:模式匹配更惯用。执行流程的分叉可能很难遵循,您会发现“提前返回”充其量可能有点令人困惑,或者最坏的情况是反模式。
考虑重构代码以在函数参数中进行模式匹配。这不仅消除了对验证函数的需要(因为模式匹配只有在这些键存在时才会成功),它允许您定义create/2
函数的多个子句。这有效地为您提供了 2 条执行路径:一种用于存在key
andtype
参数的情况,另一种用于不存在的情况。
def create(conn, %{"key" => key, "type" => type}) do
validation_func = PayeeContext.validation_map(type)
case validation_func.(key) do
{:ok, _} ->
conn |> send_resp(200, "Request created successfully")
{:error, message} -> conn |> send_resp(400, message)
end
end
def create(conn, _) do
send_resp(conn, 400, "Please provide Key and Type parameters")
end
请记住:必须先执行更具体的匹配——执行将被分派到匹配成功的第一个函数。
推荐阅读
- c# - 错误问题(当前名称在 中不存在)
- html - 如何对齐 div 和 span
- sql - 如何在 Oracle 10G 中更改列的长度(以字符为单位)?
- reactjs - DOM元素不会在反应弹簧动画中被删除
- javascript - 反应 this.state.bottles.map 不是一个函数
- ubuntu - 无法打开 OMNeT++ IDE
- python - 创建将消息作为嵌入消息移动的 Discord Bot 方法
- python - Python:TypeError 字符串索引必须是整数
- python - 超参数调优与分类算法对比
- c# - 从 Entity Framework Core 获取一个调用存储过程