gmile

gmile

Asserting on the JSON response from a controller action in OTP26

After upgrading to OTP26, we’re seeing a lot of failures related to the shape of JSON response. For example, given the view is constructed using atoms (which is how we do it), the following assertion easily fails:

output = Jason.encode!(%{one: 1, two: 2})
assert  ~s|{"one":1,"two":2}| = output

This seems in line with one of the highlights of the OTP26 release, e.g. order of atom keys in map.

Simple assertions like above are possible to re-write so that order doesn’t matter. However, in our case, we have assertions fail on significantly bigger JSONs which are extremely hard to re-write.

The above makes me question if we aren’t doing anything wrong here.

Maybe it doesn’t make sense to use atoms when constructing the view? :thinking: The reason we always did it that way was to not to pollute process memory with strings that are common - a problem which (supposedly?) doesn’t exist for the same atoms.

Maybe testing shape of the output is not a good idea in the first place? If so, then how do you test your views?

How are you people dealing with a situation similar to this?

Most Liked

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Unless I’m missing something, I don’t see how atoms vs strings are relevant here.

Testing on the string order of json keys is in general unreliable. The JSON spec makes no promise of key order, nor do Elixir maps. If you want to test the semantic equivalence of something you need to decode the JSON, not assert on a JSON string.

Ideally you simply don’t encode to a string at all and instead test:

assert %{"one" => 1, "two" => 2} == output

If it is unavoidably already encoded then just decode it:

assert %{"one" => 1, "two" => 2} == Jason.decode!(output)
hst337

hst337

Yes, you’re trying to compare JSON as strings, while standard clearly defines that order of keys in json maps may be different for the same structure.


You can try doing something like

assert %{one: 1, two: 2} == result
hst337

hst337

If those strings are larger than 64 bytes, than they’re most likely shared. Smaller strings are not shared. But still, with atoms you’re saving just a few kilobytes for huge maps

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New

We're in Beta

About us Mission Statement