RefreshDatabaseTrait is not executed in time
I was trying to use RefreshDatabaseTrait for API testing but for some reason the assert gave me 404.
<?php
namespace App\Tests\Functional;
use App\test\CustomApiTestCase;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
class UserResourceTest extends CustomApiTestCase
{
use RefreshDatabaseTrait;
public function testGetItemUser(): void
{
$client = static::createClient();
$user = $this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth)');
}
}
After a long time of testing, I found out that with this code only the first assert fails.
public function testGetItemUser(): void
{
$client = static::createClient();
$user = $this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth 1)');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth 2)');
}
It feels like the database refresh is not finishing in time so that the first user is deleted
1. database refresh start
2. Create User
3. database refresh end
nvm, I'm not even creating two users.
but it is ward because if I remove use RefreshDatabaseTrait;
the code works like this:
public function testGetItemUser(): void
{
$client = static::createClient();
$user = $this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth)');
}
Isn't it an issue with static::createClient() that re-creates a kernel with maybe a different connection?
Isn't it an issue with
static::createClient()that re-creates a kernel with maybe a different connection?
But then why does it work if I remove the use RefreshDatabaseTrait;
also, when running the full test the first two tests run true fine but when hitting the third I get an SQL Duplicate entry error for "[email protected]" but this should not be happening if the reset would have already happend.
<?php
namespace App\Tests\Functional;
use App\test\CustomApiTestCase;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
class UserResourceTest extends CustomApiTestCase
{
use RefreshDatabaseTrait;
// Tests:
// POST (no auth)
public function testPostUser(): void
{
$client = static::createClient();
// POST (no auth)
$this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$this->assertResponseStatusCodeSame(201, 'POST (no auth)');
}
// Tests:
// GET collection (no auth)
// GET collection (auth)
// GET collection (admin auth)
public function testGetCollectionUser(): void
{
$client = static::createClient();
// GET collection (no auth)
$client->request('GET', '/api/users');
$this->assertResponseStatusCodeSame(401, 'GET collection (no auth)');
// GET collection (auth)
$user = $this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$token = $this->createAuth($client, $user);
$client->request('GET', '/api/users', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]);
$this->assertResponseStatusCodeSame(403, 'GET collection (auth)');
// GET collection (admin auth)
$admin = $this->createAdmin($client, '[email protected]', 'Test_password_1!', 'Test Admin 1');
$token = $this->createAuth($client, $admin);
$client->request('GET', '/api/users', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]);
$this->assertResponseStatusCodeSame(200, 'GET collection (admin auth)');
}
// Tests:
// GET item (no auth)
// GET item (auth owne)
// GET item (auth *)
// GET item (admin auth own)
// GET item (admin auth *)
public function testGetItemUser(): void
{
$client = static::createClient();
// GET item (no auth)
$user = $this->createUser($client, '[email protected]', 'Test_password_1!', 'Test User 1');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth 2)');
$client->request('GET', '/api/users/' . $user->getId());
$this->assertResponseStatusCodeSame(401, 'GET item (no auth 2)');
}
}
I'm not sure but it looks similar to my problem.
When I load fixtures from files (use R...DatabaseTrait in test class) I can't save any new entity to the database by using EntityManager or by making a request to the api.
@renja-g confirm if it's the same in your case. If not @theofidry I'll create a new issue.
I've fixed my issue. The problem was that the "base test class" and specific "test class" use R...DatabaseTrait so it was loaded twice. With this for loaded entities as fixtures every new EntityClass was marked as MANAGED by doctrine EntityManager (UnitOfWork).
so it was loaded twice
I wonder if there would be a way to detect this and throw an error in this case?
I don't know exactly the tests flow but is bootKernel run before test-case and ensureKernelShutdown after? If yes maybe add some flag (?) there and check it?
Actually it looks like this is already handled? https://github.com/theofidry/AliceBundle/blob/master/src/PhpUnit/RefreshDatabaseTrait.php#L38 So there maybe more to it
Yes, I saw it! But ReloadDatabaseTrait is missing it.
I think this may be related to mixing up Refresh and Reload.
The fix is NOT to add what is in Refresh to Reload. The idea of Reload is to populate the database at kernel boot, if there is already fixtures a purge (via delete or truncate) is done before populating the database. So even calling it several times over should be fine (although expensive for no reasons).
Where this will get messy is if Reload is mixed up with Refresh. Indeed Refresh populates the DB once and then uses transactions to rollback. But purging with a truncate will be effective and remove the data regardless of the transaction. Calling it twice should also have no effect (besides having nested transactions).
I am not sure if this really addresses the original case, but I will close this as I cannot find anything. if you encounter the problem and want me to look into it please provide a small reproducer that I can debug.