Skip to content

Commit fd598fc

Browse files
authored
docs(testing): update testing part using foundry instead of alice (#1757)
1 parent 25aefb7 commit fd598fc

File tree

1 file changed

+50
-23
lines changed

1 file changed

+50
-23
lines changed

distribution/testing.md

+50-23
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ In this article you'll learn how to use:
1313

1414
* [PHPUnit](https://phpunit.de), a testing framework to cover your classes with unit tests and to write
1515
API-oriented functional tests thanks to its API Platform and [Symfony](https://symfony.com/doc/current/testing.html) integrations.
16-
* [Alice](https://github.com/nelmio/alice) and [its Symfony
17-
integration](https://github.com/theofidry/AliceBundle#database-testing), an expressive fixtures generator to write data fixtures.
16+
* [DoctrineFixturesBundle](https://symfony.com/bundles/DoctrineFixturesBundle/current/index.html), a bundle to load data fixtures in the database.
17+
* [Foundry](https://github.com/zenstruck/foundry), an expressive fixtures generator to write data fixtures.
1818

1919
## Creating Data Fixtures
2020

@@ -58,6 +58,8 @@ Improve the default values:
5858

5959
```php
6060
// src/Factory/ReviewFactory.php
61+
// ...
62+
use function Zenstruck\Foundry\lazy;
6163

6264
// ...
6365

@@ -156,6 +158,26 @@ The API Platform test client implements the interfaces of the [Symfony HttpClien
156158

157159
If you don't use the distribution, run `composer require --dev symfony/test-pack symfony/http-client` to install them.
158160

161+
Install [DAMADoctrineTestBundle](https://github.com/dmaicher/doctrine-test-bundle) to reset the database automatically before each test:
162+
163+
```console
164+
docker compose exec php \
165+
composer require --dev dama/doctrine-test-bundle
166+
```
167+
168+
And activate it in the `phpunit.xml.dist` file:
169+
170+
```xml
171+
<!-- api/phpunit.xml.dist -->
172+
<phpunit>
173+
<!-- ... -->
174+
175+
<extensions>
176+
<extension class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension"/>
177+
</extensions>
178+
</phpunit>
179+
```
180+
159181
Optionally, you can install [JSON Schema for PHP](https://github.com/justinrainbow/json-schema) if you want to use the [JSON Schema](https://json-schema.org) test assertions provided by API Platform:
160182

161183
```console
@@ -175,15 +197,20 @@ namespace App\Tests;
175197

176198
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
177199
use App\Entity\Book;
178-
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
200+
use App\Factory\BookFactory;
201+
use Zenstruck\Foundry\Test\Factories;
202+
use Zenstruck\Foundry\Test\ResetDatabase;
179203

180204
class BooksTest extends ApiTestCase
181205
{
182-
// This trait provided by AliceBundle will take care of refreshing the database content to a known state before each test
183-
use RefreshDatabaseTrait;
206+
// This trait provided by Foundry will take care of refreshing the database content to a known state before each test
207+
use ResetDatabase, Factories;
184208

185209
public function testGetCollection(): void
186210
{
211+
// Create 100 books using our factory
212+
BookFactory::createMany(100);
213+
187214
// The client implements Symfony HttpClient's `HttpClientInterface`, and the response `ResponseInterface`
188215
$response = static::createClient()->request('GET', '/books');
189216

@@ -263,15 +290,22 @@ publicationDate: This value should not be null.',
263290

264291
public function testUpdateBook(): void
265292
{
293+
// Only create the book we need with a given ISBN
294+
BookFactory::createOne(['isbn' => '9781344037075']);
295+
266296
$client = static::createClient();
267297
// findIriBy allows to retrieve the IRI of an item by searching for some of its properties.
268-
// ISBN 9786644879585 has been generated by Alice when loading test fixtures.
269-
// Because Alice use a seeded pseudo-random number generator, we're sure that this ISBN will always be generated.
270298
$iri = $this->findIriBy(Book::class, ['isbn' => '9781344037075']);
271299

272-
$client->request('PUT', $iri, ['json' => [
273-
'title' => 'updated title',
274-
]]);
300+
// Use the PATCH method here to do a partial update
301+
$client->request('PATCH', $iri, [
302+
'json' => [
303+
'title' => 'updated title',
304+
],
305+
'headers' => [
306+
'Content-Type' => 'application/merge-patch+json',
307+
]
308+
]);
275309

276310
$this->assertResponseIsSuccessful();
277311
$this->assertJsonContains([
@@ -283,6 +317,9 @@ publicationDate: This value should not be null.',
283317

284318
public function testDeleteBook(): void
285319
{
320+
// Only create the book we need with a given ISBN
321+
BookFactory::createOne(['isbn' => '9781344037075']);
322+
286323
$client = static::createClient();
287324
$iri = $this->findIriBy(Book::class, ['isbn' => '9781344037075']);
288325

@@ -294,22 +331,12 @@ publicationDate: This value should not be null.',
294331
static::getContainer()->get('doctrine')->getRepository(Book::class)->findOneBy(['isbn' => '9781344037075'])
295332
);
296333
}
297-
298-
public function testLogin(): void
299-
{
300-
$response = static::createClient()->request('POST', '/login', ['json' => [
301-
'email' => '[email protected]',
302-
'password' => 'admin',
303-
]]);
304-
305-
$this->assertResponseIsSuccessful();
306-
}
307334
}
308335
```
309336

310-
As you can see, the example uses the [trait `RefreshDatabaseTrait`](https://github.com/theofidry/AliceBundle#database-testing)
311-
from [AliceBundle](https://github.com/theofidry/AliceBundle) which will, at the beginning of each
312-
test, purge the database, load fixtures, begin a transaction, and, at the end of each test, roll back the
337+
As you can see, the example uses the [trait `ResetDatabase`](https://symfony.com/bundles/ZenstruckFoundryBundle/current/index.html#database-reset)
338+
from [Foundry](https://github.com/zenstruck/foundry) which will, at the beginning of each
339+
test, purge the database, begin a transaction, and, at the end of each test, roll back the
313340
transaction previously begun. Because of this, you can run your tests without worrying about fixtures.
314341

315342
There is one caveat though: in some tests, it is necessary to perform multiple requests in one test, for example when creating a user via the API and checking that a subsequent login using the same password works. However, the client will by default reboot the kernel, which will reset the database. You can prevent this by adding `$client->disableReboot();` to such tests.

0 commit comments

Comments
 (0)