I’m new to phoenix and I’m trying to make a simple json api with tests (without ecto). It exposes some endpoints such as /create that receives POSTS with a json body, and returns some more json.
I’m having some doubts on how to approach the testing and organization. For now I created a controller that calls some inner system to produce a result to give back as {"result": "something"}
and a fallback controller to handle the error cases, such as bad parameters in the given json to return a 400.
I started with the controller tests, for example:
test "error: should returns 400 when missing parameters", %{conn: conn} do
conn = post(conn, "/v1/fn/invoke", %{namespace: "a_ns"})
assert body = json_response(conn, 400)
expected_error_keys = ["detail"]
assert expected == Map.keys(body)
end
Then in the fall back controller with the related error I invoke the render from the ErrorView that just returns
the map with the error:
def render("bad_params.json", _assigns) do
%{errors: %{detail: "Failed to perform operation: bad request"}}
end
And in the error_view_test I have:
test "renders bad_params.json" do
out = %{errors: %{detail: "Failed to perform operation: bad request"}}
assert render(CoreWeb.ErrorView, "bad_params.json", []) == out
end
Initially I thought it was ok, I use the views to handle the json encoding and there is a unit test to check that the output is correct. On the controller side I only check that it is an error.
The thing that I didn’t like was that not checking what the controller actually returns doesn’t guarantee that it’s returning the right thing. I could make a typo and have the fallback controller render an nonexistent view which would fall to the 500 error one and for the tests all is good.
If I assert that the result of the controller must be that json it would be robust I think, but then what’s the point of the view tests? Should I just drop the testing of the views and do all in the controller tests?
I’d like some advice on this, but also in general for json apis in phoenix.