Do you test many_to_many Ecto assocs?

Hi all, I’m thinking about creating a many-to-many association on one of my schemas like this

    many_to_many :active_foos, MyApp.Foo,
      join_through: MyApp.FooJoinTable,
      join_where: [state: :current],
      where: [state: :active],
      preload_order: [asc: :name]

The above reads like configuration - but it feels complex enough that it might merit writing a couple of sanity tests. However there’s also advice that when it comes to tests, we should be testing our own code, not the library/framework code - and it would seem that a test like this

test "correctly loads active_foos" do
   ...
end

would be testing that many_to_many works as advertised as opposed to testing that some business logic is correct.

What have others done here? Did/would you write tests like that? Or would you rather indirectly test at the call site instead (e.g. in a test for the page that renders the active_foos).

Thanks for your thoughts!

I would be the first to tell you to not test Ecto itself, though in your case I believe it’s fair to test if those m2m records are inserted properly if f.ex. you also have metadata fields inside them, want to check if the preload order is indeed respected etc.

There’s a fine line between unfounded paranoia and simply making sure your stuff works. I’d say in this case it’s a bit of both but I’d still add tests.

3 Likes

I’d say you don’t want to test the “definition”, but you want to test the code making use of the definition according to how that powers actual usecases of your application. Tests should not break if you switch to e.g. has_many/through, if there’s no user facing behaviour changes. But things should break if you mess something up in that definition, which would result in user facing behaviour changes.

8 Likes

Thank you both for your thoughtful input.

In the end I decided to to test both that the relation returns the expected records in the order expected while leaving out unwanted ones, and also at the call site to make sure that it’s correctly used.

3 Likes