Is it possible to not load associations after insertion with ExMachina?

990 Views Asked by At

I'm using ex_machina to create fixture for my unit-tests.

I'm saving some records to the database using ExMachina insert(:comment) but my assertions are wrong because ExMachina always load relations and it's not the case when I'm fetching with Ecto and not calling Repo.preload.

Let's say I have 2 factories comment and user:

def user_factory do
  %User{
    name: "some name"
  }
end

def comment_factory do
  %Comment{
    content: "some content",
    user: build(:user)
  }
end

when I'm testing

  test "should retrieve last comment" do
    comment = fixture(:comment)
    assert Comment.get_last_comment() == comment
  end

Assertion if failing because on the left I have

%Comment{
    ...,
    content: "some content",
    user: #Ecto.Association.NotLoaded<association :user is not loaded>
}

and on the right

%Comment{
    ...,
    content: "some content",
    user: %User{ name: "some name" }
}

I'm trying to avoid:

  • using Repo.preload on my left records because sometimes there are quite a lot of dependencies

  • testing each property individually

Thanks by advance for your help

1

There are 1 best solutions below

1
On

I've tackled this problem by defining a equal_records function in test/support/data_case.ex that just compares the type of the structs and the ids of the records:

def equal_records(%{__struct__: t1, id: id1}, %{__struct__: t2, id: id2}) do
  t1 == t2 and id1 == id2
end

def equal_records(_, _), do: false

Usage:

test "should retrieve last comment" do
  comment = fixture(:comment)
  assert equal_records(Comment.get_last_comment(), comment)
end

To also test lists of records, add these functions too:

def equal_records([], []), do: true
def equal_records([h1 | t1], [h2 | t2]) do
  equal_records(h1, h2) and equal_records(t1, t2)
end