I'm learning how to write test for my Api Platform based api. I'm using Alice helper RefreshDatabaseTrait
in test class. In documentation it says that this trait wraps every test is transaction and when its done just rolls its back. Because of that when I for example delete Employee using HttpClient and want to assert it was deleted I have to initialize EmpoyeeRepository
again in order for test to pass. If i don't do it 'count()' method returns 10 Employees. Is there a problem with nested transactions or something?
class EmployeeTest extends AbstractTest
{
use RefreshDatabaseTrait;
/** @test
* @group functional
*/
public function deleteEmployee(): void
{
// Arrange
/** @var EmployeeRepository $employeeRepository */
$employeeRepository = static::getContainer()->get(EmployeeRepository::class);
/** @var Employee $employee */
$employee = $employeeRepository->findOneBy([]);
// Act
$this->createClientWithCredentials()
->request('DELETE', '/employees/' . $employee->getUuid());
// Assert
$employeeRepository = static::getContainer()->get(EmployeeRepository::class);
static::assertResponseIsSuccessful();
static::assertEquals(9, $employeeRepository->count([]));
}
}
class AbstractTest extends ApiTestcase
{
private ?string $token = null;
/**
* @throws \JsonException
*/
protected function createClientWithCredentials($token = null): Client
{
$token = $token ?: $this->getToken();
return static::createClient([], ['headers' => ['Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', 'Accept' => 'application/json']]);
}
/**
* Use other credentials if needed.
* @throws \JsonException
*/
protected function getToken($body = []): string
{
if ($this->token) {
return $this->token;
}
$response = static::createClient()->request('POST', '/token', ['json' => $body ?:
[
"email" => "[email protected]",
"password" => "pass"
]
]);
static::assertResponseIsSuccessful();
return json_decode($response->getContent())->token;
}
}
Api Platform 2.6.8, Symfony 6.0, Hautelook/Alice 2.11 Doctrine/orm 2.13.1
My Answer:
It seems like the issue you are facing is related to the way transactions are handled in your test environment. The RefreshDatabaseTrait is rolling back the transaction after each test, but it seems like the state of the repository is not being refreshed properly.
One possible solution is to manually refresh the state of the repository after performing any actions that modify the database. In your case, after deleting an Employee, you can reinitialize the EmployeeRepository to ensure that the changes are reflected in the repository.
Another approach is to ensure that the EntityManager is properly cleared after each test. You can try calling `$entityManager->clear()` after performing any database modifications to ensure that the EntityManager is in a clean state.
Additionally, you can try using the `RefreshDatabase` annotation on your test class instead of the RefreshDatabaseTrait. This annotation will ensure that the database is refreshed before each test method is executed.
Overall, it's important to ensure that the state of the database and repositories is properly managed in your test environment to avoid any issues with stale data.
Rate this post
3 of 5 based on 8884 votesComments