I'd like to write tests to validate that the SQL queries in my application return data adhering to certain constraints: namely, that return values are presented in descending insertion order. In the application, I'm using timestamps()
in my schemas to include an inserted_at
field to the DB, and querying against it in my queries (SELECT … ORDER BY inserted_at DESC
).
My trouble comes in my tests: if I have test code like
person1_params = %{name: "Tidehunter"}
{:ok, tidehunter} = People.create_person(person1_params)
person2_params = %{name: "Kunkka"}
{:ok, kunkka} = People.create_person(person2_params)
person3_params = %{name: "Windrunner"}
{:ok, windrunner} = People.create_person(person3_params)
and I'd like to assert on their order, like
people = People.get_in_order_of_recency()
assert Enum.at(people, 0).name == "Windrunner"
this fails, even though in manual tests it all appears to work. Upon inspection, I see that inserted_at
for all three records is identical. I've tried adding :timer.sleep()
calls, but it doesn't change the outcome, suggesting some batching or laziness at the Ecto/Postgrex layer.
The "simplest" solution I could think of would be some way to "force" a transaction to occur at the call site, so I could :timer.sleep(1)
between them, giving me distinct inserted_at
fields (thus the question title) but at the risk of XY problem I'm open to other suggestions. Thanks!