Reputation: 10264
I’m currently trying to test the update function of my controller, which looks like this:
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
Where things are breaking down is in my update 404 test. When I call the controller function, I’m getting an Ecto.NoResultsError
falling through.
put(build_conn(), lesson_path(build_conn(), :update, Ecto.UUID.generate), %{})
From what I understand, my ErrorView
should have kicked in to render a proper response, but that doesn’t seem to be happening in my testing environment. Instead, the exception falls all the way through. My ErrorView
works fine in dev
when I set debug_errors
to false.
Should the ErrorView
be working in tests? Or am I missing something here? If this is expected, is there any way to enable ErrorView
for the tests?
Upvotes: 0
Views: 401
Reputation: 64
I don't think Phoenix will render an error view unless you tell it to.
I personally am not a fan of the "raise if not found" approach, but I think you have to try/rescue that and explicitly render the error view. The other approach would be to use the "non-bang" version of the query (ie: get
instead of get!
) and render the error view if you get nil.
There is one bit of "magic" that you can use though: the FallbackController. You wire this up with action_fallback/1
. The docs cover this nicely, including an example implementation of a FallbackController:
https://hexdocs.pm/phoenix/Phoenix.Controller.html#action_fallback/1
Basically, your with
block tries to match on the "ok tuple" and it will return whatever it gets that doesn't match (as opposed to throwing a no-match error). Phoenix expects the action to return a conn
so wiring up the action_fallback tells it what to do if it doesn't get a conn.
I think you would need to change Lessons.update_lesson/2
to return an error rather than raise... something like {:error, :not_found}
would be standard practice and is covered in that example in the docs.
Note that generally speaking you would just make one FallbackController that all your controllers use to handle their error cases.
Upvotes: 1