Here are some examples of how to use the fixture factories.
One article with a random title, as defined in the factory on the previous page:
$article = ArticleFactory::make()->getEntity();
Two articles with different random titles:
$articles = ArticleFactory::make(2)->getEntities();
One article with title set to 'Foo':
$article = ArticleFactory::make(['title' => 'Foo'])->getEntity();
Three articles with the title set to 'Foo':
$articles = ArticleFactory::make(['title' => 'Foo'], 3)->getEntities();
or
$articles = ArticleFactory::make(3)->patchData(['title' => 'Foo'])->getEntities();
or
$articles = ArticleFactory::make(3)->setField('title', 'Foo')->getEntities();
or
$articles = ArticleFactory::make()->setField('title', 'Foo')->setTimes(3)->getEntities();
or
$articles = ArticleFactory::make([
['title' => 'Foo'],
['title' => 'Bar'],
['title' => 'Baz'],
])->getEntities();
When injecting a single string in the factory, the latter will assign the injected string to the display field of the factory's table:
$articles = ArticleFactory::make('Foo')->getEntity();
$articles = ArticleFactory::make('Foo', 3)->getEntities();
$articles = ArticleFactory::make(['Foo', 'Bar', 'Baz'])->getEntities();
In order to persist the data generated, use the method persist
instead of getEntity
resp. getEntities
:
$articles = ArticleFactory::make(3)->persist();
Do not forget to check the plugin's tests for more insights!
All examples above are using static getter to fetch a factory instance. As convenience and kinda syntactic sugar, you can use the FactoryAwareTrait::getFactory
instead.
getFactory
is more tolerant on provided name, as you can use plurals or lowercased names. All arguments passed after factory name will be cast to BaseFactory::make
.
use App\Test\Factory\ArticleFactory;
use CakephpFixtureFactories\Factory\FactoryAwareTrait;
class MyTest extends TestCase
{
use FactoryAwareTrait;
public function myTest(): void
{
// Static getter style
$article = ArticleFactory::make()->getEntity();
$article = ArticleFactory::make(['title' => 'Foo'])->getEntity();
$articles = ArticleFactory::make(3)->getEntities();
$articles = ArticleFactory::make(['title' => 'Foo'], 3)->getEntities();
// Exactly the same in FactoryAwareTrait style
$article = $this->getFactory('Article')->getEntity();
$article = $this->getFactory('Article', ['title' => 'Foo'])->getEntity();
$articles = $this->getFactory('Article', 3)->getEntities();
$articles = $this->getFactory('Article', ['title' => 'Foo'], 3)->getEntities();
}
}
The aim of the test fixture factories is to bring business coherence in your test fixtures.
This can be simply achieved using the chainable methods of your factories. As long as those return $this
, you may chain as much methods as you require.
In the following example, we make use of a method in the Article factory in order to easily create articles with a job title.
It is a simple study case, but this could be any pattern of your business logic.
$articleFactory = ArticleFactory::make(['title' => 'Foo']);
$articleFoo1 = $articleFactory->persist();
$articleFoo2 = $articleFactory->persist();
$articleJobOffer = $articleFactory->setJobTitle()->persist();
The two first articles have a title set two 'Foo'. The third one has a job title, which is randomly generated by fake, as defined in the
ArticleFactory
.
In case a given field has not been specified with faker
in the setDefaultTemplate
method, all the generated fields of a given factory
will be identical. The following
generates three articles with different random titles:
use App\Test\Factory\ArticleFactory;
use Faker\Generator;
...
$articles = ArticleFactory::make(function(ArticleFactory $factory, Generator $faker) {
return [
'title' => $faker->text,
];
}, 3)->persist();
You might come across fields storing data in array format, with a given default value set in your factories. It is possible to overwrite only a part of the array using the dot notation.
Considering for example that the field array_field
stores an array with keys key1
and key2
, you can
overwrite the value of key2
only and keep the default value of key1
as follows:
use App\Test\Factory\ArticleFactory;
...
$article = ArticleFactory::make(['array_field.key2' => 'newValue'])->getEntity();
// or
$article = ArticleFactory::make([
'array_field.key1' => 'foo',
'array_field.key2' => 'bar',
])->getEntity();
// or
$article = ArticleFactory::make()->setField('array_field.key2', 'newValue')->getEntity();