Passed
Pull Request — master (#2)
by Alex
24:05 queued 15:48
created

testInvokeWillThrowServiceNotCreatedExceptionIfTheStringConnectionCannotBeCreated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 65
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
c 1
b 0
f 0
dl 0
loc 65
rs 9.1344
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\LaminasDoctrine\Factory\Service;
6
7
use Arp\LaminasDoctrine\Config\DoctrineConfig;
8
use Arp\LaminasDoctrine\Factory\Service\EntityManagerFactory;
9
use Arp\LaminasDoctrine\Service\Configuration\ConfigurationManagerInterface;
10
use Arp\LaminasDoctrine\Service\Configuration\Exception\ConfigurationManagerException;
11
use Arp\LaminasDoctrine\Service\Connection\ConnectionManagerInterface;
12
use Arp\LaminasDoctrine\Service\Connection\Exception\ConnectionManagerException;
13
use Doctrine\DBAL\Connection;
14
use Doctrine\ORM\Configuration;
15
use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
16
use Laminas\ServiceManager\Exception\ServiceNotFoundException;
17
use PHPUnit\Framework\MockObject\MockObject;
18
use PHPUnit\Framework\TestCase;
19
use Psr\Container\ContainerInterface;
20
21
/**
22
 * @covers \Arp\LaminasDoctrine\Factory\Service\EntityManagerFactory
23
 *
24
 * @author  Alex Patterson <[email protected]>
25
 * @package ArpTest\LaminasDoctrine\Factory\Service
26
 */
27
final class EntityManagerFactoryTest extends TestCase
28
{
29
    /**
30
     * @var ContainerInterface&MockObject
31
     */
32
    private $container;
33
34
    /**
35
     * @var DoctrineConfig&MockObject
36
     */
37
    private $doctrineConfig;
38
39
    /**
40
     * @var ConfigurationManagerInterface&MockObject
41
     */
42
    private $configurationManager;
43
44
    /**
45
     * @var ConnectionManagerInterface&MockObject
46
     */
47
    private $connectionManager;
48
49
    /**
50
     * Prepare the test case dependencies
51
     */
52
    public function setUp(): void
53
    {
54
        $this->container = $this->createMock(ContainerInterface::class);
55
56
        $this->doctrineConfig = $this->createMock(DoctrineConfig::class);
57
58
        $this->configurationManager = $this->createMock(ConfigurationManagerInterface::class);
59
60
        $this->connectionManager = $this->createMock(ConnectionManagerInterface::class);
61
    }
62
63
    /**
64
     * Assert that factory is a callable instance
65
     */
66
    public function testIsInvokable(): void
67
    {
68
        $factory = new EntityManagerFactory();
69
70
        $this->assertIsCallable($factory);
71
    }
72
73
    /**
74
     * Assert a ServiceNotCreateException is thrown from __invoke() if the required 'configuration' configuration
75
     * option is missing or null
76
     *
77
     * @throws ServiceNotFoundException
78
     */
79
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConfigurationConfigIsMissing(): void
80
    {
81
        $factory = new EntityManagerFactory();
82
83
        $serviceName = 'doctrine.entitymanager.orm_default';
84
        $emConfig = [
85
            'connection' => 'FooConnectionName',
86
            // missing 'configuration' key
87
        ];
88
89
        $this->container->expects($this->once())
90
            ->method('has')
91
            ->with(DoctrineConfig::class)
92
            ->willReturn(true);
93
94
        $this->container->expects($this->once())
95
            ->method('get')
96
            ->with(DoctrineConfig::class)
97
            ->willReturn($this->doctrineConfig);
98
99
        $this->doctrineConfig->expects($this->once())
100
            ->method('getEntityManagerConfig')
101
            ->with($serviceName)
102
            ->willReturn($emConfig);
103
104
        $this->expectException(ServiceNotCreatedException::class);
105
        $this->expectExceptionMessage(
106
            sprintf(
107
                'The required \'configuration\' configuration option is missing for service \'%s\'',
108
                $serviceName
109
            )
110
        );
111
112
        $factory($this->container, $serviceName);
113
    }
114
115
    /**
116
     * Assert a ServiceNotCreateException is thrown from __invoke() if the required 'connection' configuration
117
     * option is missing or null
118
     *
119
     * @throws ServiceNotFoundException
120
     */
121
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConnectionConfigIsMissing(): void
122
    {
123
        $factory = new EntityManagerFactory();
124
125
        $serviceName = 'doctrine.entitymanager.orm_default';
126
        $emConfig = [
127
            'connection' => null,
128
            'configuration' => 'BarConfigurationName',
129
        ];
130
131
        $this->container->expects($this->once())
132
            ->method('has')
133
            ->with(DoctrineConfig::class)
134
            ->willReturn(true);
135
136
        $this->container->expects($this->once())
137
            ->method('get')
138
            ->with(DoctrineConfig::class)
139
            ->willReturn($this->doctrineConfig);
140
141
        $this->doctrineConfig->expects($this->once())
142
            ->method('getEntityManagerConfig')
143
            ->with($serviceName)
144
            ->willReturn($emConfig);
145
146
        $this->expectException(ServiceNotCreatedException::class);
147
        $this->expectExceptionMessage(
148
            sprintf(
149
                'The required \'connection\' configuration option is missing for service \'%s\'',
150
                $serviceName
151
            )
152
        );
153
154
        $factory($this->container, $serviceName);
155
    }
156
157
    /**
158
     * Assert a ServiceNotCreateException is thrown from __invoke() if the required 'configuration' object
159
     * is of an invalid type
160
     *
161
     * @throws ServiceNotFoundException
162
     */
163
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConfigurationIsInvalid(): void
164
    {
165
        $factory = new EntityManagerFactory();
166
167
        $configuration = new \stdClass(); // invalid configuration class
168
        $serviceName = 'doctrine.entitymanager.orm_default';
169
        $emConfig = [
170
            'configuration' => $configuration,
171
            'connection' => 'BarConnectionName',
172
        ];
173
174
        $this->container->expects($this->exactly(2))
175
            ->method('has')
176
            ->withConsecutive([DoctrineConfig::class], [ConfigurationManagerInterface::class])
177
            ->willReturnOnConsecutiveCalls(true, true);
178
179
        $this->container->expects($this->exactly(2))
180
            ->method('get')
181
            ->withConsecutive([DoctrineConfig::class], [ConfigurationManagerInterface::class])
182
            ->willReturnOnConsecutiveCalls($this->doctrineConfig, $this->configurationManager);
183
184
        $this->doctrineConfig->expects($this->once())
185
            ->method('getEntityManagerConfig')
186
            ->with($serviceName)
187
            ->willReturn($emConfig);
188
189
        $this->expectException(ServiceNotCreatedException::class);
190
        $this->expectExceptionMessage(
191
            sprintf(
192
                'The configuration must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
193
                Configuration::class,
194
                \stdClass::class,
195
                $serviceName
196
            )
197
        );
198
199
        $factory($this->container, $serviceName);
200
    }
201
202
    /**
203
     * Assert a ServiceNotCreateException is thrown from __invoke() if the required 'connection' object
204
     * is of an invalid type
205
     *
206
     * @throws ServiceNotFoundException
207
     */
208
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheRequiredConnectionIsInvalid(): void
209
    {
210
        $factory = new EntityManagerFactory();
211
212
        $connection = new \stdClass(); // invalid configuration class
213
214
        /** @var Configuration|MockObject $configuration */
215
        $configuration = $this->createMock(Configuration::class);
216
217
        $serviceName = 'doctrine.entitymanager.orm_default';
218
        $emConfig = [
219
            'configuration' => $configuration,
220
            'connection' => $connection,
221
        ];
222
223
        $this->container->expects($this->exactly(3))
224
            ->method('has')
225
            ->withConsecutive(
226
                [DoctrineConfig::class],
227
                [ConfigurationManagerInterface::class],
228
                [ConnectionManagerInterface::class]
229
            )
230
            ->willReturnOnConsecutiveCalls(true, true, true);
231
232
        $this->container->expects($this->exactly(3))
233
            ->method('get')
234
            ->withConsecutive(
235
                [DoctrineConfig::class],
236
                [ConfigurationManagerInterface::class],
237
                [ConnectionManagerInterface::class]
238
            )
239
            ->willReturnOnConsecutiveCalls(
240
                $this->doctrineConfig,
241
                $this->configurationManager,
242
                $this->connectionManager
243
            );
244
245
        $this->doctrineConfig->expects($this->once())
246
            ->method('getEntityManagerConfig')
247
            ->with($serviceName)
248
            ->willReturn($emConfig);
249
250
        $this->expectException(ServiceNotCreatedException::class);
251
        $this->expectExceptionMessage(
252
            sprintf(
253
                'The connection must be an object of type \'%s\'; \'%s\' provided for service \'%s\'',
254
                Connection::class,
255
                \stdClass::class,
256
                $serviceName
257
            )
258
        );
259
260
        $factory($this->container, $serviceName);
261
    }
262
263
    /**
264
     * Assert that a ServiceNotCreatedException is thrown from __invoke if the provided 'configuration'
265
     * string is not a valid configuration
266
     *
267
     * @throws ServiceNotFoundException
268
     */
269
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheStringConfigurationCannotBeFound(): void
270
    {
271
        $factory = new EntityManagerFactory();
272
273
        $configurationName = 'BarConfigurationName';
274
        $serviceName = 'doctrine.entitymanager.orm_default';
275
        $emConfig = [
276
            'configuration' => $configurationName,
277
            'connection' => 'FooConnectionName',
278
        ];
279
280
        $this->container->expects($this->exactly(2))
281
            ->method('has')
282
            ->withConsecutive(
283
                [DoctrineConfig::class],
284
                [ConfigurationManagerInterface::class]
285
            )
286
            ->willReturnOnConsecutiveCalls(true, true);
287
288
        $this->container->expects($this->exactly(2))
289
            ->method('get')
290
            ->withConsecutive(
291
                [DoctrineConfig::class],
292
                [ConfigurationManagerInterface::class]
293
            )->willReturnOnConsecutiveCalls(
294
                $this->doctrineConfig,
295
                $this->configurationManager
296
            );
297
298
        $this->doctrineConfig->expects($this->once())
299
            ->method('getEntityManagerConfig')
300
            ->with($serviceName)
301
            ->willReturn($emConfig);
302
303
        // Return false for container has() call will raise our exception for missing configuration
304
        $this->configurationManager->expects($this->once())
305
            ->method('hasConfiguration')
306
            ->with($configurationName)
307
            ->willReturn(false);
308
309
        $this->expectException(ServiceNotCreatedException::class);
310
        $this->expectExceptionMessage(
311
            sprintf(
312
                'Failed to load configuration \'%s\' for service \'%s\': '
313
                . 'The configuration has not been registered with the configuration manager',
314
                $configurationName,
315
                $serviceName
316
            )
317
        );
318
319
        $factory($this->container, $serviceName);
320
    }
321
322
    /**
323
     * Assert that a ServiceNotCreatedException is thrown from __invoke if the provided 'configuration'
324
     * string is unable to be created
325
     *
326
     * @throws ServiceNotFoundException
327
     */
328
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheStringConfigurationCannotBeCreated(): void
329
    {
330
        $factory = new EntityManagerFactory();
331
332
        $configurationName = 'BarConfigurationName';
333
        $serviceName = 'doctrine.entitymanager.orm_default';
334
        $emConfig = [
335
            'configuration' => $configurationName,
336
            'connection' => 'FooConnectionName',
337
        ];
338
339
        $this->container->expects($this->exactly(2))
340
            ->method('has')
341
            ->withConsecutive(
342
                [DoctrineConfig::class],
343
                [ConfigurationManagerInterface::class]
344
            )
345
            ->willReturnOnConsecutiveCalls(true, true);
346
347
        $this->container->expects($this->exactly(2))
348
            ->method('get')
349
            ->withConsecutive(
350
                [DoctrineConfig::class],
351
                [ConfigurationManagerInterface::class]
352
            )->willReturnOnConsecutiveCalls(
353
                $this->doctrineConfig,
354
                $this->configurationManager
355
            );
356
357
        $this->doctrineConfig->expects($this->once())
358
            ->method('getEntityManagerConfig')
359
            ->with($serviceName)
360
            ->willReturn($emConfig);
361
362
        $this->configurationManager->expects($this->once())
363
            ->method('hasConfiguration')
364
            ->with($configurationName)
365
            ->willReturn(true);
366
367
        $exceptionMessage = 'This is a test exception message for ' . __METHOD__;
368
        $exceptionCode = 123;
369
        $exception = new ConfigurationManagerException($exceptionMessage, $exceptionCode);
370
371
        $this->configurationManager->expects($this->once())
372
            ->method('getConfiguration')
373
            ->with($configurationName)
374
            ->willThrowException($exception);
375
376
        $this->expectException(ServiceNotCreatedException::class);
377
        $this->expectExceptionCode($exceptionCode);
378
        $this->expectExceptionMessage(
379
            sprintf(
380
                'Failed to load configuration \'%s\' for service \'%s\': %s',
381
                $configurationName,
382
                $serviceName,
383
                $exceptionMessage
384
            )
385
        );
386
387
        $factory($this->container, $serviceName);
388
    }
389
390
    /**
391
     * Assert that a ServiceNotCreatedException is thrown from __invoke if the provided 'connection'
392
     * string is not a valid connection
393
     *
394
     * @throws ServiceNotFoundException
395
     */
396
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheStringConnectionCannotBeFound(): void
397
    {
398
        $factory = new EntityManagerFactory();
399
400
        /** @var Configuration|MockObject $configuration */
401
        $configuration = $this->createMock(Configuration::class);
402
        $connectionName = 'FooConnectionName';
403
        $serviceName = 'doctrine.entitymanager.orm_default';
404
        $emConfig = [
405
            'configuration' => $configuration,
406
            'connection' => $connectionName,
407
        ];
408
409
        $this->container->expects($this->exactly(3))
410
            ->method('has')
411
            ->withConsecutive(
412
                [DoctrineConfig::class],
413
                [ConfigurationManagerInterface::class],
414
                [ConnectionManagerInterface::class]
415
            )
416
            ->willReturnOnConsecutiveCalls(true, true, true);
417
418
        $this->container->expects($this->exactly(3))
419
            ->method('get')
420
            ->withConsecutive(
421
                [DoctrineConfig::class],
422
                [ConfigurationManagerInterface::class],
423
                [ConnectionManagerInterface::class]
424
            )->willReturnOnConsecutiveCalls(
425
                $this->doctrineConfig,
426
                $this->configurationManager,
427
                $this->connectionManager
428
            );
429
430
        $this->doctrineConfig->expects($this->once())
431
            ->method('getEntityManagerConfig')
432
            ->with($serviceName)
433
            ->willReturn($emConfig);
434
435
        // Return false for container has() call will raise our exception for missing configuration
436
        $this->connectionManager->expects($this->once())
437
            ->method('hasConnection')
438
            ->with($connectionName)
439
            ->willReturn(false);
440
441
        $this->expectException(ServiceNotCreatedException::class);
442
        $this->expectExceptionMessage(
443
            sprintf(
444
                'Failed to load connection \'%s\' for service \'%s\': '
445
                . 'The connection has not been registered with the connection manager',
446
                $connectionName,
447
                $serviceName
448
            )
449
        );
450
451
        $factory($this->container, $serviceName);
452
    }
453
454
    /**
455
     * Assert that a ServiceNotCreatedException is thrown from __invoke if the provided 'connection'
456
     * string is unable to be created
457
     *
458
     * @throws ServiceNotFoundException
459
     */
460
    public function testInvokeWillThrowServiceNotCreatedExceptionIfTheStringConnectionCannotBeCreated(): void
461
    {
462
        $factory = new EntityManagerFactory();
463
464
        /** @var Configuration|MockObject $configuration */
465
        $configuration = $this->createMock(Configuration::class);
466
        $connectionName = 'FooConnectionName';
467
        $serviceName = 'doctrine.entitymanager.orm_default';
468
        $emConfig = [
469
            'configuration' => $configuration,
470
            'connection' => $connectionName,
471
        ];
472
473
        $this->container->expects($this->exactly(3))
474
            ->method('has')
475
            ->withConsecutive(
476
                [DoctrineConfig::class],
477
                [ConfigurationManagerInterface::class],
478
                [ConnectionManagerInterface::class]
479
            )
480
            ->willReturnOnConsecutiveCalls(true, true, true);
481
482
        $this->container->expects($this->exactly(3))
483
            ->method('get')
484
            ->withConsecutive(
485
                [DoctrineConfig::class],
486
                [ConfigurationManagerInterface::class],
487
                [ConnectionManagerInterface::class]
488
            )->willReturnOnConsecutiveCalls(
489
                $this->doctrineConfig,
490
                $this->configurationManager,
491
                $this->connectionManager
492
            );
493
494
        $this->doctrineConfig->expects($this->once())
495
            ->method('getEntityManagerConfig')
496
            ->with($serviceName)
497
            ->willReturn($emConfig);
498
499
        $this->connectionManager->expects($this->once())
500
            ->method('hasConnection')
501
            ->with($connectionName)
502
            ->willReturn(true);
503
504
        $exceptionMessage = 'This is a test exception message for ' . __METHOD__;
505
        $exceptionCode = 123;
506
        $exception = new ConnectionManagerException($exceptionMessage, $exceptionCode);
507
508
        $this->connectionManager->expects($this->once())
509
            ->method('getConnection')
510
            ->with($connectionName)
511
            ->willThrowException($exception);
512
513
        $this->expectException(ServiceNotCreatedException::class);
514
        $this->expectExceptionCode($exceptionCode);
515
        $this->expectExceptionMessage(
516
            sprintf(
517
                'Failed to load connection \'%s\' for service \'%s\': %s',
518
                $connectionName,
519
                $serviceName,
520
                $exceptionMessage
521
            )
522
        );
523
524
        $factory($this->container, $serviceName);
525
    }
526
}
527