Настройка пользовательского ответа для исключения в приложении Phoenix

im писать приложение phoenix с помощью ecto и иметь следующий фрагмент в тесте

{:ok, data} = Poison.encode(%{email: "[email protected]", password: "mypass"})

conn()
|> put_req_header("content-type", "application/json")
|> put_req_header("accept", "application/json")
|> post(session_path(@endpoint, :create), data)
> json_response(:not_found) == %{}

это вызывает Ecto.NoResultsError

i имеет этот определенный

defimpl Plug.Exception, for: Ecto.NoResultsError do
  def status(_exception), do: 404
end

но тест по-прежнему вызывает Ecto.NoResultsError, любые указатели?

Ответ 1

Давайте рассмотрим, как он работает для каждой среды.

  • В :prod по умолчанию отображаются страницы с ошибками, поэтому вы должны увидеть страницу, отображаемую YourApp.ErrorView, с кодом состояния;

  • В :dev по умолчанию отображаются страницы отладки, так как в большинстве случаев у вас возникает ошибка при создании кода. Если вы хотите увидеть фактическую страницу с ошибкой, вам нужно установить debug_errors: false в config/dev.exs;

  • В :test он работает как производство, но, поскольку вы вызываете свое приложение из теста, ваш тест также выйдет из строя, если ваше приложение выйдет из строя. Мы улучшаем это в будущих версиях, где вы должны написать что-то вроде:

    assert_raise Ecto.NoResultsError, fn ->
      get conn, "/foo"
    end
    {status, headers, body} = sent_response(conn)
    assert status == 404
    assert body =~ "oops"
    

Ответ 2

Phoenix 1.1.0 представил Phoenix.ConnTest.assert_error_sent/2, чтобы облегчить тестирование подобных случаев.

Из документация:

Утверждается, что ошибка была завершена и отправлена ​​с заданным статусом.

Полезно для тестирования действий, которые вы ожидаете, вызывают ошибку и имеют ответ, завернутый в статус HTTP, с контентом, обычно отображаемым вашим MyApp.ErrorView.

Пример использования:

assert_error_sent :not_found, fn ->
  get conn(), "/users/not-found"
end

response = assert_error_sent 404, fn ->
  get conn(), "/users/not-found"
end
assert {404, [_h | _t], "Page not found"} = response