View Source FactoryEx behaviour (factory_ex v0.3.4)

FactoryEx

Coverage Test Dialyzer Credo codecov Hex version badge

Installation

Available in Hex, the package can be installed by adding factory_ex to your list of dependencies in mix.exs:

def deps do
  [
    {:factory_ex, "~> 0.1.0"}
  ]
end

Documentation can be found at https://hexdocs.pm/factory_ex.

Using

For defining your own factories just implement schema/0, repo/0 and build/0 callback e.g:

defmodule MyFactory do
  @behaviour FactoryEx

  def schema, do: MySchema

  def repo, do: MyRepo

  def build(params \\ %{}) do
    default = %{
      foo: 21,
      bar: 42
    }

    Map.merge(default, params)
  end
end

And then using it in your tests as:

# For getting a default parameter struct.
FactoryEx.build(MyFactory)

# For getting a default parameter struct with a modification.
FactoryEx.build(MyFactory, foo: 42)

# For getting a default parameter struct and not validating the changeset
FactoryEx.build(MyFactory, [foo: 42], validate?: false)

# For getting a default parameter map.
FactoryEx.build_params(MyFactory)

# For getting a default parameter map with a modification..
FactoryEx.build_params(MyFactory, foo: 10)

# For getting a default parameter map and not validating the changeset
FactoryEx.build_params(MyFactory, foo: 10, validate?: false)

# For getting multiple default parameter maps
FactoryEx.build_many_params(MyFactory, [foo: 42])

# For getting an invalid parameter maps
FactoryEx.build_invalid_params(MyFactory, [foo: 42])

# For inserting a default schema.
FactoryEx.insert!(MyFactory)

# For inserting a default schema with a modification.
FactoryEx.insert!(MyFactory, foo: 42)

# For inserting multiple default schema
FactoryEx.insert_many!(10, MyFactory, foo: 42)

Using FactoryEx.SchemaCounter

In order to avoid duplicate data on fields and guarentee unique data, we can use FactoryEx.SchemaCounter to generate unique integers to append to our fields.

For example our factory could look like the following:

defmodule MyFactory do
  @behaviour FactoryEx

  def schema, do: MySchema

  def repo, do: MyRepo

  def build(params \\ %{}) do
    default = %{
      foo: FactoryEx.SchemaCounter.next("my_factory_foo"),
      bar: FactoryEx.SchemaCounter.next("my_factory_bar")
    }

    Map.merge(default, params)
  end
end

To utilize FactoryEx.SchemaCounter, we must call FactoryEx.SchemaCounter.start() in the test/test_helper.exs file.

Generating Factories

FactoryEx comes with a helpful mix command to generate factories into our application

$ mix factory_ex.gen --repo FactoryEx.Support.Repo FactoryEx.Support.Accounts.User
$ mix factory_ex.gen --repo FactoryEx.Support.Repo FactoryEx.Support.{Accounts.{User,Role},Authentication.{Token,Session}}

To read more info run mix factory_ex.gen

FactoryEx.build options

We can also specify options to &FactoryEx.build/3

  • :keys - Sets the type of keys to have in the built object, can be one of :atom, :string or :camel_string

Summary

Callbacks

Callback that returns a map with valid defaults for the schema.

Callback that returns a struct with valid defaults for the schema.

Callback that returns the schema's repo module.

Callback that returns the schema module.

Functions

Builds a schema given the factory module and an optional list/map of params.

Builds many parameters for a schema changeset/2 function given the factory module and an optional list/map of params.

Builds the parameters for a schema changeset/2 function given the factory module and an optional list/map of params.

Removes all the instances of a schema from the database given its factory module.

Inserts a schema given the factory module and an optional list/map of params. Fails on error.

Insert as many as count schemas given the factory module and an optional list/map of params.

Types

@type build_opts() :: [{:keys, :atom | :string | :camel_string}]

Callbacks

@callback build(map()) :: map()

Callback that returns a map with valid defaults for the schema.

Link to this callback

build_struct(map)

View Source (optional)
@callback build_struct(map()) :: struct()

Callback that returns a struct with valid defaults for the schema.

@callback repo() :: module()

Callback that returns the schema's repo module.

@callback schema() :: module()

Callback that returns the schema module.

Functions

Link to this function

build(module, params \\ %{}, options \\ [])

View Source

Builds a schema given the factory module and an optional list/map of params.

Link to this function

build_invalid_params(module)

View Source
@spec build_invalid_params(module()) :: map()
Link to this function

build_many_params(count, module, params \\ %{}, opts \\ [])

View Source
@spec build_many_params(pos_integer(), module(), keyword() | map(), build_opts()) :: [
  map()
]

Builds many parameters for a schema changeset/2 function given the factory module and an optional list/map of params.

Link to this function

build_params(module, params \\ %{}, opts \\ [])

View Source
@spec build_params(module(), keyword() | map(), build_opts()) :: map()

Builds the parameters for a schema changeset/2 function given the factory module and an optional list/map of params.

Link to this function

cleanup(module, options \\ [])

View Source

Removes all the instances of a schema from the database given its factory module.

Link to this function

insert!(module, params \\ %{}, options \\ [])

View Source
@spec insert!(module(), keyword() | map(), Keyword.t()) ::
  Ecto.Schema.t() | no_return()

Inserts a schema given the factory module and an optional list/map of params. Fails on error.

Link to this function

insert_many!(count, module, params \\ %{}, options \\ [])

View Source

Insert as many as count schemas given the factory module and an optional list/map of params.