Closed wesnick closed 3 years ago
What kind of mocking do you need? Can you please provide more detailed example?
BTW: This on will fail, as job is not pushed yet
Queue::fake();
DB::transaction(function () {
TestJob::dispatch();
Queue::assertPushedOn('lol', TestJob::class);
});
This one will be successful
Queue::fake();
DB::transaction(function () {
TestJob::dispatch();
});
Queue::assertPushedOn('lol', TestJob::class);
Hi, sorry for not getting back sooner.
Here is an example of how I am verifying a Job was pushed to the Queue when this library is enabled: NOTE: the following is pseudo-code.
public function testPost()
{
$myPayload = ['foo' => 'bar'];
// POST to an endpoint that has a model listener that pushes a job,
// this controller must create several database objects and so is nested in a transaction
$response = $this->postJson('/my-endpoint', $myPayload);
$myModelId = $response->json('data.id');
$d = app(Dispatcher::class);
if ($d instanceof TransactionalDispatcher) {
$refl = new \ReflectionClass($d);
$reflProp = $refl->getProperty('pendingCommands');
$reflProp->setAccessible(true);
$commands = $reflProp->getValue($d);
$jobs = array_pop($commands);
$ids = Arr::pluck($jobs, 'my_model.id');
$this->assertTrue(in_array($myModelId, $ids, true));
}
}
I would like to be able to follow the existing pattern in Laravel for mocking the Queue.
public function setUp()
{
// something like this...
Dispatcher::fake();
}
then in my Test
public function testPost()
{
$myPayload = ['foo' => 'bar'];
// POST to an endpoint that has a model listener that pushes a job,
// this controller must create several database objects and so is nested in a transaction
$response = $this->postJson('/my-endpoint', $myPayload);
$myModelId = $response->json('data.id');
$d = app(Dispatcher::class);
$d->assertPushed(MyJob::class, function (MyJob $job) use ($myModelId) {
return $job->my_model->id === $myModelId;
});
I can collaborate on or author a PR depending on how you want to this to work.
After you run post request, job should be in queue $d->assertPushed() should work fine; Please update to latest version and try that approach again.
Ah, right, I see now my test uses the DatabaseTransactions trait, so the job never gets enqueued because transaction level starts at 1 and never reaches 0. This is the underlying issue.
Great. So I am closing this issue for now. If you need some functionality to test pending jobs stack, let me know. Also feel free to make PRs with improvements.... Have a nice day.
This is the pattern I am using now in tests when this AfterTransactions is enabled on Jobs
public function setUp(): void
{
parent::setUp();
Queue::fake;
}
public function testSomething()
{
// ... some code that generates a Job...
Queue::hasPushed(MyJob::class); // false
$d = app(Dispatcher::class);
$d->commitTransaction(); // Does not actually commit, just decrements the counter and pushes the jobs to the faked queue
Queue::hasPushed(MyJob::class); // true
}
Hi,
In a normal test you might mock the Queue
How can I do this when this library is enabled? Outside of reflection and I don't see how I can do this