首页 > 解决方案 > 为什么我的 ErrorView 没有在测试中呈现?

问题描述

我目前正在尝试测试我的控制器的更新功能,如下所示:

def update(conn, params = %{"id" => id}) do
  lesson_params = Map.delete(params, "id")
  lesson = Lessons.get_lesson!(id)
  with {:ok, %Lesson{} = lesson} <- Lessons.update_lesson(lesson, lesson_params) do
    json(conn, LessonSerializer.to_map(lesson))
  end
end

我的更新 404 测试中出现了问题。当我调用控制器功能时,我遇到了Ecto.NoResultsError挫折。

put(build_conn(), lesson_path(build_conn(), :update, Ecto.UUID.generate), %{})

据我了解,我ErrorView应该开始做出正确的响应,但这似乎并没有在我的测试环境中发生。相反,异常始终贯穿始终。当我设置为时,我的ErrorView工作正常devdebug_errorsfalse.

应该ErrorView在测试中工作吗?或者我在这里错过了什么?如果这是预期的,有什么方法可以启用ErrorView测试吗?

标签: elixirphoenix-framework

解决方案


除非您告诉它,否则我认为 Phoenix 不会呈现错误视图。

我个人不喜欢“如果找不到就提高”方法,但我认为你必须尝试/拯救它并明确呈现错误视图。另一种方法是使用查询的“非爆炸”版本(即:get而不是get!)并在获得 nil 时呈现错误视图。

不过,您可以使用一点“魔法”:FallbackController。你用action_fallback/1. 文档很好地涵盖了这一点,包括一个 FallbackController 的示例实现:

https://hexdocs.pm/phoenix/Phoenix.Controller.html#action_fallback/1

基本上,您的with块尝试在“ok tuple”上进行匹配,并且它将返回任何不匹配的内容(而不是引发不匹配错误)。Phoenix 期望动作返回一个conn所以连接 action_fallback 告诉它如果没有得到一个 conn 该怎么做。

我认为您需要进行更改Lessons.update_lesson/2以返回错误而不是引发...类似的{:error, :not_found}做法将是标准做法,并且在文档中的该示例中进行了介绍。

请注意,一般来说,您只需创建一个 FallbackController ,所有控制器都使用它来处理它们的错误情况。


推荐阅读