Closed nathan-de-pachtere closed 1 year ago
Hey! I'll look a bit deeper shortly but first, do any of those other traits or base test class have any @before
methods that manipulate messenger (ie $this->transport('<name>')->unblock();
?
@kbond Nope, none of them are manipulating messenger
trait HasCompany
{
protected Company|Proxy $company;
protected User|Proxy $owner;
protected User|Proxy $collaborator;
protected function setUp(): void
{
list($company, $owner, $collaborator) = $this->createCompanyTeam();
$this->company = $company;
$this->owner = $owner;
$this->collaborator = $collaborator;
}
protected function tearDown(): void
{
$this->deleteCompany($this->owner, $this->company);
}
}
trait CompanyTestTrait
{
protected function createCompanyTeam(array $collaboratorPermissions = Permission::ALL): array
{
list($company, $owner) = $this->createCompanyAndOwner();
$collaborator = $this->addCollaboratorToCompany($company, $collaboratorPermissions);
return [
$company, $owner, $collaborator,
];
}
protected function createCompanyAndOwner(string $legalForm = Company::LEGAL_FORM_EI): array
{
$owner = UserFactory::new()->verified()->create();
$company = CompanyFactory::new()->create([
'creator' => $owner,
'legalForm' => $legalForm,
])->disableAutoRefresh();
return [
$company, $owner,
];
}
protected function getCompanyIri(Company|Proxy $company): string
{
return $this->findIriBy(Company::class, ['id' => $company->getId()]);
}
protected function addCollaboratorToCompany(Company|Proxy $company, array $permissions = Permission::ALL): User|Proxy
{
$collaborator = UserFactory::new()->verified()->create();
CompanyMemberFactory::new()->create([
'company' => $company,
'user' => $collaborator,
'permissions' => $permissions,
]);
return $collaborator;
}
protected function deleteCompany(User|Proxy $owner, Company|Proxy $company): void
{
$this->browser()->actingAs($owner)->delete($this->getCompanyIri($company))->dump()->assertStatus(204);
}
}
Other trait are from Zenstruck and the base class is from ApiPlatform.
Does removing @before
from this method make any difference?
What's going on in the line that triggers the exception?
/var/www/tests/Functional/Review/StatisticsReviewResourceTest.php:88
@kbond Nope, still the same error.
If it's easier for you, we can make a visio with code sharing ;) I'm also working on a reproducer, in a clean empty project.
I'm also working on a reproducer, in a clean empty project.
This would be very helpful if you can do this!
What's going on in the line that triggers the exception?
/var/www/tests/Functional/Review/StatisticsReviewResourceTest.php:88
Just creating some Reviewers with Factory
ReviewerFactory::createMany(3, [
'company' => $this->company
]);
It must be something related to the @before
hooks. Are you using PHPUnit 9?
Yes PHPUnit 9.6.6 by Sebastian Bergmann and contributors.
I'm not able to reproduce the exact same error. I mean, I can reproduce a db related error only on "even number" test second and fourth. But not able to get the queue_name messenger related error.
Sharing my work for now (still working on it) https://github.com/nathan-de-pachtere/messenger-test-fail-reproducer
Just to complet the error
1) App\Tests\Functional\Review\StatisticsReviewResourceTest::testIncrementNumberOfRefusedByReviewer
Undefined array key "statistic"
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:349
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:266
/var/www/vendor/symfony/messenger/Middleware/SendMessageMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/FailedMessageProcessingMiddleware.php:34
/var/www/vendor/symfony/messenger/Middleware/DispatchAfterCurrentBusMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/RejectRedeliveredMessageMiddleware.php:41
/var/www/vendor/symfony/messenger/Middleware/AddBusNameStampMiddleware.php:37
/var/www/vendor/symfony/messenger/Middleware/TraceableMiddleware.php:40
/var/www/vendor/symfony/messenger/MessageBus.php:70
/var/www/vendor/symfony/messenger/TraceableMessageBus.php:38
/var/www/vendor/zenstruck/messenger-test/src/Bus/TestBus.php:38
/var/www/src/Statistics/Listener/NumberOfReviewersCreatedListener.php:20
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php:93
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1175
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:431
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:403
/var/www/vendor/zenstruck/foundry/src/Proxy.php:147
/var/www/vendor/zenstruck/foundry/src/Factory.php:151
/var/www/vendor/zenstruck/foundry/src/FactoryCollection.php:77
/var/www/vendor/zenstruck/foundry/src/ModelFactory.php:39
/var/www/tests/Functional/Review/StatisticsReviewResourceTest.php:38
ERRORS!
Tests: 3, Assertions: 27, Errors: 1.
Remaining indirect deprecation notices (10)
Session.php on line 44:
""
Don't know what is this Session.php on line 44 stuff printing at the end
I really don't understand how the same test can be valid half the time depend on the last test. I mean if you run the same test 4 time first and third going to be ok but second and fourth gonna crash.
class StatisticsReviewResourceTest extends ApiTestCase
{
public function testIncrementNumberOfReviewersCreated()
{
$statistics = $this->company->getStatisticsReview();
$this->assertEquals(0, $statistics->getNumberOfReviewersCreated());
$numberOfReviewersToCreate = 4;
ReviewerFactory::createMany($numberOfReviewersToCreate, [
'company' => $this->company
]);
$this->transport('statistic')->queue()->assertCount($numberOfReviewersToCreate);
$this->transport('statistic')->queue()->assertContains(StatisticsReviewNumberOfReviewersCreatedMessage::class, $numberOfReviewersToCreate);
$this->transport('statistic')->process();
$this->company->refresh();
$statistics = $this->company->getStatisticsReview();
$this->assertEquals($numberOfReviewersToCreate, $statistics->getNumberOfReviewersCreated());
}
public function testIncrementNgumberOfReviewersCreated()
{
$statistics = $this->company->getStatisticsReview();
$this->assertEquals(0, $statistics->getNumberOfReviewersCreated());
$numberOfReviewersToCreate = 4;
ReviewerFactory::createMany($numberOfReviewersToCreate, [
'company' => $this->company
]);
$this->transport('statistic')->queue()->assertCount($numberOfReviewersToCreate);
$this->transport('statistic')->queue()->assertContains(StatisticsReviewNumberOfReviewersCreatedMessage::class, $numberOfReviewersToCreate);
$this->transport('statistic')->process();
$this->company->refresh();
$statistics = $this->company->getStatisticsReview();
$this->assertEquals($numberOfReviewersToCreate, $statistics->getNumberOfReviewersCreated());
}
public function testIncrementdNumberOfReviewersCreated()
{
$statistics = $this->company->getStatisticsReview();
$this->assertEquals(0, $statistics->getNumberOfReviewersCreated());
$numberOfReviewersToCreate = 4;
ReviewerFactory::createMany($numberOfReviewersToCreate, [
'company' => $this->company
]);
$this->transport('statistic')->queue()->assertCount($numberOfReviewersToCreate);
$this->transport('statistic')->queue()->assertContains(StatisticsReviewNumberOfReviewersCreatedMessage::class, $numberOfReviewersToCreate);
$this->transport('statistic')->process();
$this->company->refresh();
$statistics = $this->company->getStatisticsReview();
$this->assertEquals($numberOfReviewersToCreate, $statistics->getNumberOfReviewersCreated());
}
public function testIncrementfNumberOfReviewersCreated()
{
$statistics = $this->company->getStatisticsReview();
$this->assertEquals(0, $statistics->getNumberOfReviewersCreated());
$numberOfReviewersToCreate = 4;
ReviewerFactory::createMany($numberOfReviewersToCreate, [
'company' => $this->company
]);
$this->transport('statistic')->queue()->assertCount($numberOfReviewersToCreate);
$this->transport('statistic')->queue()->assertContains(StatisticsReviewNumberOfReviewersCreatedMessage::class, $numberOfReviewersToCreate);
$this->transport('statistic')->process();
$this->company->refresh();
$statistics = $this->company->getStatisticsReview();
$this->assertEquals($numberOfReviewersToCreate, $statistics->getNumberOfReviewersCreated());
}
}
result in
php -d memory_limit=-1 ./vendor/bin/phpunit tests/Functional/Review/StatisticsReviewResourceTest.php
PHPUnit 9.6.6 by Sebastian Bergmann and contributors.
Testing App\Tests\Functional\Review\StatisticsReviewResourceTest
.E.E 4 / 4 (100%)
Saved Browser Artifacts:
App\Tests\Functional\Review\StatisticsReviewResourceTest::testIncrementNgumberOfReviewersCreated
Saved Source Files:
* ./var/browser/source/error_App-Tests-Functional-Review-StatisticsReviewResourceTest__testIncrementNgumberOfReviewersCreated__0.html:
App\Tests\Functional\Review\StatisticsReviewResourceTest::testIncrementfNumberOfReviewersCreated
Saved Source Files:
* ./var/browser/source/error_App-Tests-Functional-Review-StatisticsReviewResourceTest__testIncrementfNumberOfReviewersCreated__0.html:
Time: 00:25.358, Memory: 92.50 MB
There were 2 errors:
1) App\Tests\Functional\Review\StatisticsReviewResourceTest::testIncrementNgumberOfReviewersCreated
Undefined array key "statistic"
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:349
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:266
/var/www/vendor/symfony/messenger/Middleware/SendMessageMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/FailedMessageProcessingMiddleware.php:34
/var/www/vendor/symfony/messenger/Middleware/DispatchAfterCurrentBusMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/RejectRedeliveredMessageMiddleware.php:41
/var/www/vendor/symfony/messenger/Middleware/AddBusNameStampMiddleware.php:37
/var/www/vendor/symfony/messenger/Middleware/TraceableMiddleware.php:40
/var/www/vendor/symfony/messenger/MessageBus.php:70
/var/www/vendor/symfony/messenger/TraceableMessageBus.php:38
/var/www/vendor/zenstruck/messenger-test/src/Bus/TestBus.php:38
/var/www/src/Statistics/Listener/NumberOfReviewersCreatedListener.php:20
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php:93
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1175
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:431
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:403
/var/www/vendor/zenstruck/foundry/src/Proxy.php:147
/var/www/vendor/zenstruck/foundry/src/Factory.php:151
/var/www/vendor/zenstruck/foundry/src/FactoryCollection.php:77
/var/www/vendor/zenstruck/foundry/src/ModelFactory.php:39
/var/www/tests/Functional/Review/StatisticsReviewResourceTest.php:39
2) App\Tests\Functional\Review\StatisticsReviewResourceTest::testIncrementfNumberOfReviewersCreated
Undefined array key "statistic"
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:349
/var/www/vendor/zenstruck/messenger-test/src/Transport/TestTransport.php:266
/var/www/vendor/symfony/messenger/Middleware/SendMessageMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/FailedMessageProcessingMiddleware.php:34
/var/www/vendor/symfony/messenger/Middleware/DispatchAfterCurrentBusMiddleware.php:68
/var/www/vendor/symfony/messenger/Middleware/RejectRedeliveredMessageMiddleware.php:41
/var/www/vendor/symfony/messenger/Middleware/AddBusNameStampMiddleware.php:37
/var/www/vendor/symfony/messenger/Middleware/TraceableMiddleware.php:40
/var/www/vendor/symfony/messenger/MessageBus.php:70
/var/www/vendor/symfony/messenger/TraceableMessageBus.php:38
/var/www/vendor/zenstruck/messenger-test/src/Bus/TestBus.php:38
/var/www/src/Statistics/Listener/NumberOfReviewersCreatedListener.php:20
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/Event/ListenersInvoker.php:93
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:1175
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php:431
/var/www/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:403
/var/www/vendor/zenstruck/foundry/src/Proxy.php:147
/var/www/vendor/zenstruck/foundry/src/Factory.php:151
/var/www/vendor/zenstruck/foundry/src/FactoryCollection.php:77
/var/www/vendor/zenstruck/foundry/src/ModelFactory.php:39
/var/www/tests/Functional/Review/StatisticsReviewResourceTest.php:77
ERRORS!
Tests: 4, Assertions: 30, Errors: 2.
Remaining indirect deprecation notices (10)
Session.php on line 44:
""
I mean, I can reproduce a db related error only on "even number" test second and fourth. But not able to get the queue_name messenger related error.
Not sure if related to this issue but in your reproducer but:
https://github.com/nathan-de-pachtere/messenger-test-fail-reproducer/blob/7f949c86efcd55e00dac7ef5cbdd83d65e4c085a/tests/Functional/MainTest.php#L38 causes the db error. You actually can remove this entire method really as the db is reset because you're using the ResetDatabase
trait.
Ok, just as a test, I threw a flush after the ->remove() call in the link above and now I get the Undefined array key "statistic"
error every other test! This seems related.
Can you remove
protected function tearDown(): void
{
$this->deleteCompany($this->owner, $this->company);
}
from your HasCompany
trait and see if that fixes?
Ok, I believe the issue was with your tearDown()
not calling parent::tearDown()
.
Again though, you shouldn't need to delete entities in tearDown()
, @after
methods when using the ResetDatabase
trait.
If you want to keep the tearDown
method, ensure parent::tearDown()
is called after your logic.
Ok, I believe the issue was with your
tearDown()
not callingparent::tearDown()
.Again though, you shouldn't need to delete entities in
tearDown()
,@after
methods when using theResetDatabase
trait.If you want to keep the
tearDown
method, ensureparent::tearDown()
is called after your logic.
I need that delete on my Company entity to clean third party elements (S3 Bucket, Stripe, etc... ) in test environment. The ResetDatabase doesn't trigger lifecycle events that why I'm doing this cleanup even if I'm using the ResetDatabaseTrait (who perform a doctrine:schema:drop). Maybe it's not the good way, but I like to keep all my environments as clean as possible and at the same time check if users can delete their companies environments (through api call) what ever they are doing (all my other tests)
I made this changes to the tearDown() function in ApiTestCase class, and it's working! Thanks for your help and your precious time!
/** @after */
protected function cleanCompany(): void
{
$this->deleteCompany($this->owner, $this->company);
parent::tearDown();
}
I still don't understand why this happens to this particular test with those PreRemove hooks triggered. It is because the kernel was not shutdown properly, so the reset messenger get wrong ? But what the link between this and the hooks ...
Maybe it's not the good way, but I like to keep all my environments as clean as possible and at the same time check if users can delete their companies environments (through api call) what ever they are doing (all my other tests)
That makes perfect sense.
I still don't understand why this happens to this particular test with those PreRemove hooks triggered. It is because the kernel was not shutdown properly, so the reset messenger get wrong ? But what the link between this and the hooks ...
I think the issue is the methods marked as @after
are called after tearDown
(which shuts down the kernel)
Hello,
I have an error when running multiple tests. What I mean by "running multiple tests" is when launching test over a test file with multiple testFunction().
These are the class dispatching messages :
My test file
If I remove the dispatch from NumberOfReviewersCreatedListener.php:20 I got the same error but slightly different and on all tests (2, 3 , 4) (first test fail cause there is no more message dispatched)
If one you got an idea of what happening it would be a great help ! Thanks