Skip to content

Commit a549c10

Browse files
authored
docs: using factories in data providers (#707)
1 parent 470d927 commit a549c10

File tree

3 files changed

+82
-7
lines changed

3 files changed

+82
-7
lines changed

docs/index.rst

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1607,7 +1607,68 @@ PHPUnit Data Providers
16071607
~~~~~~~~~~~~~~~~~~~~~~
16081608

16091609
It is possible to use factories in
1610-
`PHPUnit data providers <https://phpunit.readthedocs.io/en/9.3/writing-tests-for-phpunit.html#data-providers>`_:
1610+
`PHPUnit data providers <https://phpunit.readthedocs.io/en/9.3/writing-tests-for-phpunit.html#data-providers>`_.
1611+
Their usage depends on which Foundry version you are running:
1612+
1613+
Data Providers with Foundry ^2.2
1614+
................................
1615+
1616+
From version 2.2, Foundry provides an extension for PHPUnit.
1617+
You can install it by modifying you ``phpunit.xml.dist``:
1618+
1619+
.. configuration-block::
1620+
1621+
.. code-block:: xml
1622+
1623+
<phpunit>
1624+
<extensions>
1625+
<bootstrap class="Zenstruck\Foundry\PHPUnit\FoundryExtension"/>
1626+
</extensions>
1627+
</phpunit>
1628+
1629+
.. warning::
1630+
1631+
This PHPUnit extension requires at least PHPUnit 11.4.
1632+
1633+
Using this extension will allow to use your factories in your data providers the same way you're using them in tests.
1634+
Thanks to it, you can:
1635+
* Call ``->create()`` or ``::createOne()`` or any other method which creates objects in unit tests
1636+
(using ``PHPUnit\Framework\TestCase``) and functional tests (``Symfony\Bundle\FrameworkBundle\Test\KernelTestCase``)
1637+
* Use `Factories as Services`_ in functional tests
1638+
* Use `faker()` normally, without wrapping its call in a callable
1639+
1640+
::
1641+
1642+
use App\Factory\PostFactory;
1643+
use PHPUnit\Framework\Attributes\DataProvider;
1644+
1645+
#[DataProvider('createMultipleObjectsInDataProvider')]
1646+
public function test_post_via_data_provider(Post $post): void
1647+
{
1648+
// at this point, `$post` exists, and is already stored in database
1649+
}
1650+
1651+
public static function postDataProvider(): iterable
1652+
{
1653+
yield [PostFactory::createOne()];
1654+
yield [PostWithServiceFactory::createOne()];
1655+
yield [PostFactory::createOne(['body' => faker()->sentence()];
1656+
}
1657+
1658+
1659+
.. warning::
1660+
1661+
Because Foundry is relying on its `Proxy mechanism <object-proxy>`_, when using persistence,
1662+
your factories must extend ``Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory`` to work in your data providers.
1663+
1664+
.. warning::
1665+
1666+
For the same reason, you should not call methods from `Proxy` class in your data providers,
1667+
not even ``->_real()``.
1668+
1669+
1670+
Data Providers before Foundry v2.2
1671+
..................................
16111672

16121673
::
16131674

tests/Integration/DataProvider/DataProviderForServiceFactoryInKernelTestCaseTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use Zenstruck\Foundry\Tests\Fixture\Factories\Object1Factory;
2525
use Zenstruck\Foundry\Tests\Fixture\Object1;
2626

27+
use function Zenstruck\Foundry\faker;
28+
2729
/**
2830
* @author Nicolas PHILIPPE <[email protected]>
2931
* @requires PHPUnit 11.4
@@ -34,23 +36,21 @@ final class DataProviderForServiceFactoryInKernelTestCaseTest extends KernelTest
3436
{
3537
use Factories;
3638

37-
/**
38-
* @test
39-
*/
4039
#[Test]
4140
#[DataProvider('createObjectFromServiceFactoryInDataProvider')]
42-
public function it_can_create_one_object_in_data_provider(?Object1 $providedData): void
41+
public function it_can_create_one_object_in_data_provider(?Object1 $providedData, string $expected): void
4342
{
4443
self::assertFalse(Configuration::instance()->inADataProvider());
4544

4645
self::assertInstanceOf(Object1::class, $providedData);
47-
$this->assertSame('router-constructor', $providedData->getProp1());
46+
$this->assertSame($expected, $providedData->getProp1());
4847
}
4948

5049
public static function createObjectFromServiceFactoryInDataProvider(): iterable
5150
{
5251
yield 'service factory' => [
53-
Object1Factory::createOne(),
52+
Object1Factory::createOne(['prop1' => $prop1 = faker()->sentence()]),
53+
"$prop1-constructor"
5454
];
5555
}
5656
}

tests/Integration/DataProvider/DataProviderInUnitTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Zenstruck\Foundry\Tests\Fixture\Object1;
2929
use Zenstruck\Foundry\Tests\Fixture\Object2;
3030

31+
use function Zenstruck\Foundry\faker;
3132
use function Zenstruck\Foundry\Persistence\unproxy;
3233

3334
/**
@@ -65,4 +66,17 @@ public static function createObjectWithPersistentObjectFactoryInDataProvider():
6566
yield 'persistent factory' => [GenericEntityFactory::createOne(), new GenericEntity('default1')];
6667
yield 'proxy persistent factory' => [GenericProxyEntityFactory::createOne(), new GenericEntity('default1')];
6768
}
69+
70+
#[Test]
71+
#[DataProvider('createObjectUsingFakerInDataProvider')]
72+
public function assert_it_can_create_use_faker_in_data_provider(mixed $providedData, string $expected): void
73+
{
74+
self::assertSame($expected, $providedData->getProp1());
75+
}
76+
77+
public static function createObjectUsingFakerInDataProvider(): iterable
78+
{
79+
yield 'object factory' => [Object1Factory::createOne(['prop1' => $prop1 = faker()->sentence()]), "$prop1-constructor"];
80+
yield 'persistent factory' => [GenericEntityFactory::createOne(['prop1' => $prop1 = faker()->sentence()]), $prop1];
81+
}
6882
}

0 commit comments

Comments
 (0)