sf8193
Unit testing phoenix with put does not change map
Hello!
I’m trying to do a unit test with ex_machina like so
test "renders errors when data is invalid", %{conn: conn, group: group, shipment: shipment, route: route} do
conn = put conn, group_shipment_route_path(conn, :update, group, shipment, route), route: params_for(:invalid_route)
assert html_response(conn, 200) =~ "Edit Route"
end
end
where the value I want to place in looks like this
def invalid_route_factory do
%Route{
label: nil
}
end
my changeset and schema looking like this
schema "routes" do
field :label, :string, null: false
field :address, :string
field :date, :string
field :groups, :string
field :checklist, {:array, :string}
belongs_to :shipment, Shipment # on_delete set in database via migration
timestamps()
end
@doc false
def changeset(route, attrs) do
route
|> cast(attrs, [:address, :date, :groups, :label, :shipment_id, :checklist])
|> validate_required([:label, :shipment_id])
end
end
and the function I am trying to test looking like this
def update(conn, %{"route" => route_params} = params) do
{ group_id, shipment_id, route_id } = get_ids(params)
route = Shipments.get_route!(route_id)
case Shipments.update_route(route, route_params) do
{:ok, route} ->
conn
|> put_flash(:info, "Route updated successfully.")
|> redirect(to: group_shipment_route_path(conn, :show, group_id, shipment_id, route))
{:error, %Ecto.Changeset{} = changeset} ->
render(conn, "edit.html", group: group_id, shipment: shipment_id, route: route, changeset: changeset)
end
end
the error I get indicates that the case returns {:ok, route} rather than :error, which should not be the case since :label should be validated against null as you can see in my schema.
This is the error I get that indicates I get {:ok, route}, and in my conn struct I see the route wasn’t created from my ex_machina factory.
1) test update route renders errors when data is invalid (FerryWeb.RouteControllerTest)
test/ferry_web/controllers/route_controller_test.exs:69
** (RuntimeError) expected response with status 200, got: 302, with body:
<html><body>You are being <a href="/groups/74/shipments/183/routes/120">redirected</a>.</body></html>
code: assert html_response(conn, 200) =~ "Edit Route"
stacktrace:
(phoenix) lib/phoenix/test/conn_test.ex:362: Phoenix.ConnTest.response/2
(phoenix) lib/phoenix/test/conn_test.ex:376: Phoenix.ConnTest.html_response/2
test/ferry_web/controllers/route_controller_test.exs:75: (test)
Is there anyway I can debug why this is happening?
Marked As Solved
sf8193
I figured it out, the issue was with the ex_machina library. If you put something as “nil”, it will not include it in the struct, which is why I couldn’t get my test to go down the “error” branch of my code
Also Liked
benwilson512
This is just an issue with your test case actually.
What this is saying is that the HTTP PUT request you made in your test case got a 302 response. The 302 response is the redirection response code. If you look at your update controller function, this is exactly what you tell it to do:
When you hit the update function from your browser, it gets the 302 status code and immediately redirects to the show page, which can make it less obvious that two independent HTTP requests happen. However in your test case there isn’t an automatic redirect follow that happens.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








