Fixtures for Ecto
Fixture files should be stored in test/fixtures/
. The format of a
fixture file is as:
# test/fixtures/accounts.exs
accounts model: Account, repo: Repo do
test do
email "[email protected]"
name "Brian Cardarella"
password_hash :crypto.hash(:sha, "password")
end
end
In your test file you can access the fixture sets with the
by tagging each test with the fixtures you want to load then
pattern matching on the data
field for the context
argument.
defmodule MyTestCase do
use ExUnit.Case
use EctoFixtures
@tag fixtures: :accounts
test "data test", %{data: data} do
assert data.accounts.test.email == "[email protected]"
end
end
This data is also inserted into the database, the resulting data set
returned from fixtures/1
is actually an Ecto.Model
.
defmodule MyTestCase do
use ExUnit.Case
use EctoFixtures
test "database data is inserted and equal to data set", %{data: data} do
assert data.accounts.test == Repo.get(Account, accounts.test.id)
end
end
If you'd like the model structs without actually inserting into the
database pass insert: false
to fixtures/2
.
defmodule MyTestCase do
use ExUnit.Case
import EctoFixtures, only: [fixtures: 2]
test "database data is inserted and equal to data set" do
fixtures(:accounts, insert: false)
assert length(Repo.all(Account)) == 0
end
end
You can override the fixture data on a per-usage basis by passing a map as the 2nd argument. The maps keys must correspond with the structure of the fixture names and row names column data you wish to override.
Note: you cannot add rows with the override. It is intended only to mutate the fixture column data
defmodule MyTestCase do
use ExUnit.Case
import EctoFixtures, only: [fixtures: 2]
test "data test" do
%{accounts: accounts} = fixtures(:accounts, %{
accounts: %{
test: %{
email: "[email protected]"
}
}
})
assert accounts.test.email != "[email protected]"
assert accounts.test.email == "[email protected]"
end
end
Associations can be made between data sets, reference the data set's name and label:
accounts model: Account, repo: Repo do
brian do
name "Brian"
end
end
events model: Event, repo: Repo do
one do
name "First Event"
account accounts.brian
end
end
accounts model: Account, repo: Repo do
brian do
name "Brian"
pet pets.boomer
end
end
pets model: Pet, repo: Repo do
boomer do
name "Boomer"
end
end
accounts model: Account, repo: Repo do
brian do
name "Brian"
events [events.one, events.two]
end
end
events model: Event, repo: Repo do
one do
name "First Event"
end
two do
name "Second Event"
end
end
Associations can also be made between fixture files:
# test/fixtures/accounts.exs
accounts model: Account, repo: Repo do
brian do
name "Brian"
pet fixtures(:pets).pets.boomer
end
end
# test/fixtures/pets.exs
pets model: Pet, repo: Repo do
boomer do
name "Boomer"
end
end
ecto_fixtures will determine the assocation type being made and ensure that child records are always inserted after the parent record to avoid any foreign key constraint issues, regardless of the order in which the fixtures are loaded.
If you'd like to have default values inherited into other rows you can
do that with the inherit
option on the row defintion:
accounts model: Account, repo: Repo do
default do
is_admin false
end
brian inherits: default do
name "Brian"
end
end
other_accounts: Account, repo: Repo do
stephanie inherits: accounts.default do
name "Stephanie"
is_admin true
end
end
When inheriting from rows in the same group you can simply refer to the row name. When referring to rows in other groups you have to refer to the group name and table name.
You can inherit data from other fixture files as well:
# test/fixtures/accounts.exs
accounts model: Account, repo: Repo do
default do
is_admin false
end
brian inherits: default do
name "Brian"
end
end
# test/fixtures/other_accounts.exs
other_accounts: Account, repo: Repo do
stephanie inherits: fixtures(:accounts).accounts.default do
name "Stephanie"
is_admin true
end
end
Inherited values can be overriden by defining values on the same column.
Sometimes you may not want the row you inherit from to be inserted into
the database. In this case you must set the virtual: true
flag for
that row:
accounts model: Account, repo: repo do
default virtual: true do
is_admin false
end
end
We are very thankful for the many contributors
This library follows Semantic Versioning
Please do! We are always looking to improve this library. Please see our Contribution Guidelines on how to properly submit issues and pull requests.
DockYard, Inc. ยฉ 2015