Controller and view tests for phoenix json API

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)

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"}}

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

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.

1 Like