1
votes

I've been playing around with Elixir Phoenix and have a simple integration test that checks that a json response of a model is the same as the json-rendered representation of that model.

The test looks like this:

test "#show renders a single link" do
    conn = get_authenticated_conn()
    link = insert(:link)

    conn = get conn, link_path(conn, :show, link)

    assert json_response(conn, 200) == render_json(LinkView, "show.json", link: link)
end

This used to work fine but following a recent mix deps.update the test has broken due a precision problem with the timestamps of the model. Here is the output from the test:

Assertion with == failed
     code: json_response(conn, 200) == render_json(LinkView, "show.json", link: link)
     lhs:  %{"id" => 10, "title" => "A handy site to find stuff on the internet", "url" => "http://google.com", "inserted_at" => "2017-01-09T19:27:57.000000", "updated_at" => "2017-01-09T19:27:57.000000"}
     rhs:  %{"id" => 10, "title" => "A handy site to find stuff on the internet", "url" => "http://google.com", "inserted_at" => "2017-01-09T19:27:56.606085", "updated_at" => "2017-01-09T19:27:56.606093"}

We can see that the timestamps of the response given by the controller compared to the json rendering of the model do not match. This is because the MySQL database (5.7) rounds microseconds down to 0 whilst the in-memory Ecto model representation supports higher accuracy. My migration just uses Ecto's timestamps function.

What's the best way to get these tests to pass? I don't particularly care about microsecond precision for my timestamps but clearly Ecto has made it more accurate in a recent update. I have a feeling it might be a problem with MariaEx but not sure how to solve.

1
Try adding @timestamps_opts [usec: false] just above the schema "..." do call in the relevant model(s). That should make Ecto behave like before and not use microsecond precision.Dogbert
That does the trick! Many thanks, post as answer and I'll acceptharryg

1 Answers

0
votes

As mentioned in the Ecto v2.1 CHANGELOG, to get the old behavior of not keeping usec in automatic timestamps (like it was until Ecto < v2.1), you can add the following module attribute just before the call to schema in the relevant model(s):

@timestamps_opts [usec: false]