Integrating with ExMachina

View Source

ExMachina is a popular library for generating test data in Elixir. Blink works seamlessly with ExMachina, allowing you to combine ExMachina's expressive factories with Blink's high-performance bulk insertion.

  • ExMachina: Generates realistic, varied test data with factories
  • Blink: Performs fast bulk insertions into PostgreSQL

Together, they provide the best of both worlds: expressive data generation with efficient database seeding.

Setting up ExMachina

Add ExMachina to your dependencies in mix.exs:

defp deps do
  [
    {:ex_machina, "~> 2.7", only: [:dev, :test]}
  ]
end

Install the dependencies:

mix deps.get

Creating factories

Create a factory module:

defmodule Blog.Factory do
  use ExMachina

  def user_factory do
    %{
      name: Faker.Person.name(),
      email: Faker.Internet.email()
    }
  end

  def post_factory do
    %{
      title: Faker.Lorem.sentence(),
      body: Faker.Lorem.paragraph()
    }
  end
end

Note: To use Faker, add {:faker, "~> 0.18", only: [:dev, :test]} to your dependencies.

Basic integration

Use ExMachina's build/1 function in your Blink seeder:

defmodule Blog.Seeders.BlogSeeder do
  use Blink
  import Blog.Factory

  def call do
    new()
    |> add_table("users")
    |> insert(Blog.Repo)
  end

  def table(_store, "users") do
    for i <- 1..1000 do
      user = build(:user)

      Map.merge(user, %{
        id: i,
        inserted_at: ~U[2024-01-01 00:00:00Z],
        updated_at: ~U[2024-01-01 00:00:00Z]
      })
    end
  end
end

ExMachina generates the names and emails, while you control the IDs and timestamps.

Using sequences

ExMachina provides sequences for unique values:

defmodule Blog.Factory do
  use ExMachina

  def user_factory do
    %{
      name: Faker.Person.name(),
      email: sequence(:email, &"user#{&1}@example.com"),
      username: sequence(:username, &"user#{&1}")
    }
  end
end

Use them in your seeder:

def table(_store, "users") do
  for i <- 1..1000 do
    user = build(:user)

    Map.merge(user, %{
      id: i,
      inserted_at: ~U[2024-01-01 00:00:00Z],
      updated_at: ~U[2024-01-01 00:00:00Z]
    })
  end
end

Each user will have a unique email and username generated by ExMachina's sequences.

Summary

In this guide, we learned how to:

  • Set up ExMachina for data generation
  • Use ExMachina's build/1 function with Blink seeders
  • Work with sequences for unique values

For more information: