在elixirphoenix中的集成测试中,早期返回无法工作。

问题描述 投票:1回答:1

我是一个完全陌生的Elixir,但是当使用Node时,我们做了很多早期回报,但我遇到了一些问题,使早期回报般的代码在我的集成测试中工作。这是我的问题。

我的控制器中有这样一个方法,它接收一个JSON作为param,我需要验证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 integration-testing phoenix early-return
1个回答
3
投票

在Elixir中,If-statements是很少见的:模式匹配是比较习惯的。 执行流的分叉可能很难遵循,你会发现 "早期返回 "在最好的情况下可能有点混乱,或者在最坏的情况下是一个反模式。

考虑重构你的代码,在函数参数中进行模式匹配。这不仅消除了对验证函数的需求(因为模式匹配只有在这些键存在的情况下才会成功),它允许你定义多个子句的 create/2 函数。 这实际上给你提供了2条执行路径:一条用于当 keytype 参数,而当参数不存在时,则执行另一个函数。

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

记住:更具体的匹配必须先进行--执行将被派往匹配成功的第一个函数。

© www.soinside.com 2019 - 2024. All rights reserved.