Skip to content

Commit 6c98389

Browse files
authored
Don't mock what you don't own (#66)
* Do not rely on mock for Doctrine manager nor registry * Do not rely on mock for event dispatcher * Do not rely on mock for symfony normalizer nor denormalizer * Remove phpspec/prophecy-phpunit dev dependency from packages that are no longer using it
1 parent b6f494e commit 6c98389

File tree

3 files changed

+74
-52
lines changed

3 files changed

+74
-52
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yokai\Batch\Tests\Dummy;
6+
7+
use Psr\EventDispatcher\EventDispatcherInterface;
8+
9+
final class DebugEventDispatcher implements EventDispatcherInterface
10+
{
11+
/**
12+
* @var object[]
13+
*/
14+
private array $events = [];
15+
16+
/**
17+
* @var array<string, callable[]>
18+
*/
19+
private array $listeners = [];
20+
21+
public function dispatch(object $event)
22+
{
23+
$this->events[] = $event;
24+
foreach ($this->listeners[\get_class($event)] ?? [] as $listener) {
25+
$listener($event);
26+
}
27+
}
28+
29+
public function addListener(string $event, callable $listener): void
30+
{
31+
$this->listeners[$event] ??= [];
32+
$this->listeners[$event][] = $listener;
33+
}
34+
35+
/**
36+
* @return object[]
37+
*/
38+
public function getEvents(): array
39+
{
40+
return $this->events;
41+
}
42+
}

tests/Job/JobExecutorTest.php

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Prophecy\Argument;
1010
use Prophecy\PhpUnit\ProphecyTrait;
1111
use Prophecy\Prophecy\ObjectProphecy;
12-
use Psr\EventDispatcher\EventDispatcherInterface;
1312
use Throwable;
1413
use Yokai\Batch\BatchStatus;
1514
use Yokai\Batch\Event\ExceptionEvent;
@@ -20,41 +19,31 @@
2019
use Yokai\Batch\JobExecution;
2120
use Yokai\Batch\Registry\JobRegistry;
2221
use Yokai\Batch\Test\Storage\InMemoryJobExecutionStorage;
22+
use Yokai\Batch\Tests\Dummy\DebugEventDispatcher;
2323
use Yokai\Batch\Warning;
2424

2525
class JobExecutorTest extends TestCase
2626
{
2727
use ProphecyTrait;
2828

29-
private const JOB_NAME = 'phpunit';
30-
31-
/**
32-
* @var ObjectProphecy&JobInterface
33-
*/
34-
private ObjectProphecy $job;
35-
36-
/**
37-
* @var ObjectProphecy&EventDispatcherInterface
38-
*/
39-
private ObjectProphecy $dispatcher;
40-
29+
private JobInterface|ObjectProphecy $job;
30+
private DebugEventDispatcher $dispatcher;
4131
private JobExecutor $executor;
4232

4333
protected function setUp(): void
4434
{
4535
$this->job = $this->prophesize(JobInterface::class);
46-
$this->dispatcher = $this->prophesize(EventDispatcherInterface::class);
47-
36+
$this->dispatcher = new DebugEventDispatcher();
4837
$this->executor = new JobExecutor(
49-
JobRegistry::fromJobArray([self::JOB_NAME => $this->job->reveal()]),
38+
JobRegistry::fromJobArray(['test.job_executor' => $this->job->reveal()]),
5039
new InMemoryJobExecutionStorage(),
51-
$this->dispatcher->reveal()
40+
$this->dispatcher
5241
);
5342
}
5443

5544
public function testLaunch(): void
5645
{
57-
$execution = JobExecution::createRoot('123', self::JOB_NAME);
46+
$execution = JobExecution::createRoot('123', 'test.job_executor');
5847
$this->job->execute($execution)
5948
->shouldBeCalledTimes(1)
6049
->will(function (array $args): void {
@@ -66,11 +55,6 @@ public function testLaunch(): void
6655

6756
$this->executor->execute($execution);
6857

69-
$this->dispatcher->dispatch(Argument::type(PreExecuteEvent::class))
70-
->shouldHaveBeenCalledTimes(1);
71-
$this->dispatcher->dispatch(Argument::type(PostExecuteEvent::class))
72-
->shouldHaveBeenCalledTimes(1);
73-
7458
self::assertNotNull($execution->getStartTime());
7559
self::assertNotNull($execution->getEndTime());
7660
self::assertSame(BatchStatus::COMPLETED, $execution->getStatus()->getValue());
@@ -79,26 +63,23 @@ public function testLaunch(): void
7963
self::assertStringContainsString('DEBUG: Starting job', $logs);
8064
self::assertStringContainsString('INFO: Job executed successfully', $logs);
8165
self::assertStringContainsString('DEBUG: Job produced summary', $logs);
66+
$events = $this->dispatcher->getEvents();
67+
self::assertCount(2, $events);
68+
self::assertInstanceOf(PreExecuteEvent::class, $events[0] ?? null);
69+
self::assertInstanceOf(PostExecuteEvent::class, $events[1] ?? null);
8270
}
8371

8472
/**
8573
* @dataProvider errors
8674
*/
8775
public function testLaunchJobCatchErrors(Throwable $error): void
8876
{
89-
$execution = JobExecution::createRoot('123', self::JOB_NAME);
77+
$execution = JobExecution::createRoot('123', 'test.job_executor');
9078
$this->job->execute($execution)
9179
->willThrow($error);
9280

9381
$this->executor->execute($execution);
9482

95-
$this->dispatcher->dispatch(Argument::type(PreExecuteEvent::class))
96-
->shouldHaveBeenCalledTimes(1);
97-
$this->dispatcher->dispatch(Argument::type(ExceptionEvent::class))
98-
->shouldHaveBeenCalledTimes(1);
99-
$this->dispatcher->dispatch(Argument::type(PostExecuteEvent::class))
100-
->shouldHaveBeenCalledTimes(1);
101-
10283
self::assertNotNull($execution->getStartTime());
10384
self::assertNotNull($execution->getEndTime());
10485
self::assertSame(BatchStatus::FAILED, $execution->getStatus()->getValue());
@@ -107,54 +88,55 @@ public function testLaunchJobCatchErrors(Throwable $error): void
10788
$logs = (string)$execution->getLogs();
10889
self::assertStringContainsString('DEBUG: Starting job', $logs);
10990
self::assertStringContainsString('ERROR: Job did not executed successfully', $logs);
91+
$events = $this->dispatcher->getEvents();
92+
self::assertCount(3, $events);
93+
self::assertInstanceOf(PreExecuteEvent::class, $events[0] ?? null);
94+
self::assertInstanceOf(ExceptionEvent::class, $events[1] ?? null);
95+
self::assertInstanceOf(PostExecuteEvent::class, $events[2] ?? null);
11096
}
11197

11298
public function testLaunchErrorWithStatusListener(): void
11399
{
114-
$execution = JobExecution::createRoot('123', self::JOB_NAME);
100+
$execution = JobExecution::createRoot('123', 'test.job_executor');
115101
$this->job->execute($execution)
116102
->willThrow($exception = new \RuntimeException());
117103

118-
$this->dispatcher->dispatch(Argument::type(ExceptionEvent::class))
119-
->shouldBeCalledTimes(1)
120-
->will(function (array $args) use ($exception) {
121-
/** @var ExceptionEvent $event */
122-
$event = $args[0];
104+
$this->dispatcher->addListener(
105+
ExceptionEvent::class,
106+
function (ExceptionEvent $event) use ($exception) {
123107
Assert::assertSame($exception, $event->getException());
124108
$event->setStatus(BatchStatus::COMPLETED);
125-
});
109+
}
110+
);
126111

127112
$this->executor->execute($execution);
128113

129-
$this->dispatcher->dispatch(Argument::type(PreExecuteEvent::class))
130-
->shouldHaveBeenCalledTimes(1);
131-
$this->dispatcher->dispatch(Argument::type(PostExecuteEvent::class))
132-
->shouldHaveBeenCalledTimes(1);
133-
134114
self::assertNotNull($execution->getStartTime());
135115
self::assertNotNull($execution->getEndTime());
136116
self::assertSame(BatchStatus::COMPLETED, $execution->getStatus()->getValue());
137117
$logs = (string)$execution->getLogs();
138118
self::assertStringContainsString('DEBUG: Starting job', $logs);
139119
self::assertStringContainsString('INFO: Job executed successfully', $logs);
120+
$events = $this->dispatcher->getEvents();
121+
self::assertCount(3, $events);
122+
self::assertInstanceOf(PreExecuteEvent::class, $events[0] ?? null);
123+
self::assertInstanceOf(ExceptionEvent::class, $events[1] ?? null);
124+
self::assertInstanceOf(PostExecuteEvent::class, $events[2] ?? null);
140125
}
141126

142127
public function testLaunchJobNotExecutable(): void
143128
{
144129
$this->job->execute(Argument::any())
145130
->shouldNotBeCalled();
146131

147-
$execution = JobExecution::createRoot('123', self::JOB_NAME, new BatchStatus(BatchStatus::COMPLETED));
132+
$execution = JobExecution::createRoot('123', 'test.job_executor', new BatchStatus(BatchStatus::COMPLETED));
148133
$this->executor->execute($execution);
149134

150-
$this->dispatcher->dispatch(Argument::type(PreExecuteEvent::class))
151-
->shouldNotHaveBeenCalled();
152-
$this->dispatcher->dispatch(Argument::type(PostExecuteEvent::class))
153-
->shouldNotHaveBeenCalled();
154-
155135
$logs = (string)$execution->getLogs();
156136
self::assertStringContainsString('WARNING: Job execution not allowed to be executed', $logs);
157137
self::assertStringNotContainsString('DEBUG: Starting job', $logs);
138+
$events = $this->dispatcher->getEvents();
139+
self::assertCount(0, $events);
158140
}
159141

160142
public function errors(): \Generator

tests/Launcher/SimpleJobLauncherTest.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use PHPUnit\Framework\TestCase;
88
use Prophecy\PhpUnit\ProphecyTrait;
9-
use Psr\EventDispatcher\EventDispatcherInterface;
109
use Yokai\Batch\BatchStatus;
1110
use Yokai\Batch\Factory\JobExecutionFactory;
1211
use Yokai\Batch\Job\JobExecutionAccessor;
@@ -24,7 +23,6 @@ class SimpleJobLauncherTest extends TestCase
2423
public function test(): void
2524
{
2625
$job = $this->prophesize(JobInterface::class);
27-
$dispatcher = $this->prophesize(EventDispatcherInterface::class);
2826

2927
$launcher = new SimpleJobLauncher(
3028
new JobExecutionAccessor(
@@ -34,7 +32,7 @@ public function test(): void
3432
new JobExecutor(
3533
JobRegistry::fromJobArray(['phpunit' => $job->reveal()]),
3634
$jobExecutionStorage,
37-
$dispatcher->reveal()
35+
null
3836
)
3937
);
4038

0 commit comments

Comments
 (0)