Forgery v0.2.0 Forgery behaviour View Source
Forgery is a slim yet extensible data generator in Elixir.
Forgery provides a few simple APIs to work with. To get started, you
need to implement the make/2
callback:
defmodule User do
defstruct [:id, :name, :password]
end
defmodule MyFactory do
use Forgery
def make(:user, fields) do
fields
|> put_new_field(:id, lazy(make_unique_integer()))
|> put_new_field(:name, &("user#" <> Integer.to_string(&1.id)))
|> create_struct(User)
end
end
iex> import MyFactory
iex>
iex> %User{} = make(:user)
iex> %User{id: 42, name: "user#42"} = make(:user, id: 42)
iex> [%User{}, %User{}] = make_many(:user, 2)
And just as simple as that!
Ecto integration
Forgery was built with easy Ecto integration in mind, though not limiting to it.
For example if you use Ecto and have MyRepo
. You can add a function, says insert!
, into the factory:
defmodule MyFactory do
def insert!(factory_name, fields \ %{}) do
factory_name
|> make(fields)
|> MyRepo.insert!()
end
def insert_many!(factory_name, amount, fields \ %{}) when amount >= 1 do
[%schema{} | _] = entities = make_many(factory_name, amount, fields)
{_, persisted_entities} = MyRepo.insert_all(schema, entities, returning: true)
persisted_entities
end
end
user = insert!(:user)
users = insert_many!(:user, 10, %{password: "1234567890"})
Link to this section Summary
Functions
Create struct of module
from fields
.
Wraps the given expr
into an anonymous function.
Returns monotonically increasing unique integer. It would be useful when it comes to generate unique serial IDs.
Lazily evaluates value_setter
and puts the result into key
if it does not exist in fields
.
Link to this section Types
Link to this section Functions
Create struct of module
from fields
.
See Kernel.struct!/2
for more information.
iex> create_struct(%{id: 1, name: "John", password: "123456"}, User)
%User{id: 1, password: "123456", name: "John"}
Wraps the given expr
into an anonymous function.
It is equivalent to fn _ -> expr end
.
Returns monotonically increasing unique integer. It would be useful when it comes to generate unique serial IDs.
Lazily evaluates value_setter
and puts the result into key
if it does not exist in fields
.
The value_setter
function receives fields
as an argument.
iex> make_foo = fn _ -> raise("I am invoked") end
iex> fields = %{foo: 1}
iex> put_new_field(fields, :foo, make_foo)
%{foo: 1}
iex> put_new_field(fields, :bar, &(&1.foo + 100))
%{foo: 1, bar: 101}
There is also helper macro lazy/1
:
iex> fields = %{foo: 2}
iex> put_new_field(fields, :foo, lazy(10 * 10))
%{foo: 2}
Link to this section Callbacks
make(factory_name, fields)
View Sourcemake(factory_name(), fields :: Enumerable.t()) :: any()
Makes data from the given factory.
The implementation of this callback should take in the factory name, as well and fields
.
make_many(factory_name, amount, fields)
View Sourcemake_many(factory_name(), amount :: integer(), fields :: Enumerable.t()) :: [ any() ]
Make multiple data from the given factory.
This function is roughly equivalent to:
Enum.map(1..amount, fn _ -> make(factory_name) end)
Example
make_many(:users, 3)
[
%User{id: 3, password: nil, name: "user#3"},
%User{id: 5, password: nil, name: "user#5"},
%User{id: 7, password: nil, name: "user#7"}
]