Testing Queries in the ExUnit

I am testing the queries in the ExUnit but I don’t know how to assert them to make the tests pass.

Here is the code:

   test "returns the query where field like" do
opts = %{
  "$where" => %{"first_name" => %{"$like" => "%Ham %"}}
}

  assert build(QM.Test.Model, opts) ==  

This is what console returns

  left:  #Ecto.Query<from m in QM.Test.Model,
         where: like(m.first_name, ^"%Ham %")>

How do I assert the query to make it pass

Thanks

2 Likes

How about testing the results of the query instead of the query itself (that is, run the query against a test database and verify the results)?

Actually I have to test the query not the result from db.

Why are you testing Ecto itself? It’s a quite well tested library. Test your domain logic.

He could be testing the function build which takes the input above and returns an ecto query. In such cases pure tests that avoid the DB are ideal.

@script you’ll want to create an equivalent query and assert equality:

expected = from m in QM.Test.Model,
  where: like(m.first_name, ^"%Ham %")

assert build(QM.Test.Model, opts) == expected
4 Likes

The goal is to see if correct query is building up by the build.

Thanks I will give it a try.

That doesn’t seem to work . The difference is in the file path. Here is the console output:

   left:  %Ecto.Query{assocs: [], distinct: nil, from: {"", QM.Test.Model}, group_bys: [], havings: [], joins: [], limit: nil, lock: nil, offset: nil, order_bys: [], prefix: nil, preloads: [], select: nil, sources: nil, updates: [], wheres: [%Ecto.Query.BooleanExpr{expr: {:like, [], [{{:., [], [{:&, [], [0]}, :first_name]}, [], []}, {:^, [], [0]}]}, op: :and, params: [{"%Ham %", :string}], file: "lib/query/where.ex", line: 121}]}
 right: %Ecto.Query{assocs: [], distinct: nil, from: {"", QM.Test.Model}, group_bys: [], havings: [], joins: [], limit: nil, lock: nil, offset: nil, order_bys: [], prefix: nil, preloads: [], select: nil, sources: nil, updates: [], wheres: [%Ecto.Query.BooleanExpr{expr: {:like, [], [{{:., [], [{:&, [], [0]}, :first_name]}, [], []}, {:^, [], [0]}]}, op: :and, params: [{"%Ham %", :string}], file: "/home/sherlock/Documents/Company/elixir_umbrella/apps/fat_ecto/test/QM Test Cases/where QM.exs", line: 13}]}

If you see in the last under file.They both point to two different files.One point to the file where build function is written and the other to the test file.

And it failed

I am using fat_ecto lib and writing test cases in it.Here is the link

@script try this
expected = from m in QM.Test.Model,
where: like(m.first_name, ^"%Ham %")

result = build(QM.Test.Model, opts)
assert inspect(result) == inspect(expected)

2 Likes

Is it fair to say the Elixir community does not often write pure functional tests around Ecto queries?

I’ve seen examples of tests using Ecto.Changeset.apply_changes/1, which is what’s suggested in the Programming Ecto book. But I’ve not seen much examples of functional testing done that assert on the Ecto.Query structs. Is testing with an actual database the best bet here?

Most of the struct is opaque, and there are no tools available to inspect those opaque parts, so there is nothing to test…

1 Like

Not always IMO. I’ve seen a fair bit of such tests in the projects I participated in:

expected = #...make Ecto query here, f.ex.: from(o in Order, where: id in ^list_of_ids, where: ordered_at > ^sometime, order_by: [desc: inserted_at])
actual = YourModule.function_returning_query(...params...)
assert inspect(expected) == inspect(actual)

Clumsy but it got the job done many times.

1 Like

Yes I think that is fair to say. In a large part because of the niceties of Ecto.Sandbox that allows for parallel testing even when using an external DB.

2 Likes

All true, maybe with one exception: libraries. I co-authored a library that builds queries (given parameters). In these cases it definitely made sense to have both: (1) compare the inspect output of expected and actual queries and (2) test them against a DB.

1 Like