Inserting fixtures in a Phoenix app with contexts

Hi! I’m building a Fixture module for testing in a Phoenix 1.3 app with contexts.

How do you generally handle fixture insertion in this case? :

  • Through contexts functions as much as possible, as they’re probably already there (Accounts.create_user, Accounts.create_team, etc)?
  • Directly with schemas changesets and bang Repo functions (Repo.insert!, etc)?
  • Without changesets / pure SQL?

I like having fixture insertion to raise if something goes wrong (with Repo.insert! with the bang).
If you prefer inserting fixture through context functions, do you duplicate Accounts.create_team and create a bang version Accounts.create_team!?
There could be a lot of duplicated code just to have the bang version.

Small example:

defmodule MyApp.Accounts do
  def create_organization(attrs \\ %{}) do
    %Organization{}
    |> Organization.changeset(attrs)
    |> Repo.insert()
  end

  # Bang version, duplicated code
  def create_organization!(attrs \\ %{}) do
    %Organization{}
    |> Organization.changeset(attrs)
    |> Repo.insert!()
  end
end
defmodule MyApp.Fixture do
  @organization %{
    name: "Pied Piper"
  }

  def insert_organization(attrs \\ %{}) do
    Map.merge(@organization, attrs)
    |> MyApp.Accounts.create_organization!() # bang version used here
  end
end

Context functions usually contain business logic, so I don’t use them for text fixtures.

There’s a simple fixture pattern described in chapter 7 of whats new in Ecto 2

5 Likes

@mbuhot I missed that chapter. It’s clean and simple. Thanks a lot!