Complex classes like QueueTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use QueueTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
12 | final class QueueTest extends TestCase |
||
13 | { |
||
14 | private $collection; |
||
15 | private $mongoUrl; |
||
16 | private $queue; |
||
17 | |||
18 | public function setUp() |
||
19 | { |
||
20 | $this->mongoUrl = getenv('TESTING_MONGO_URL') ?: 'mongodb://localhost:27017'; |
||
21 | $mongo = new \MongoDB\Client( |
||
22 | $this->mongoUrl, |
||
23 | [], |
||
24 | ['typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']] |
||
25 | ); |
||
26 | $this->collection = $mongo->selectDatabase('testing')->selectCollection('messages'); |
||
27 | $this->collection->drop(); |
||
28 | |||
29 | $this->queue = new Queue($this->mongoUrl, 'testing', 'messages'); |
||
30 | } |
||
31 | |||
32 | /** |
||
33 | * @test |
||
34 | * @covers ::__construct |
||
35 | * @expectedException \InvalidArgumentException |
||
36 | */ |
||
37 | public function constructWithNonStringUrl() |
||
41 | |||
42 | /** |
||
43 | * @test |
||
44 | * @covers ::ensureGetIndex |
||
45 | */ |
||
46 | public function ensureGetIndex() |
||
71 | |||
72 | /** |
||
73 | * @test |
||
74 | * @covers ::ensureGetIndex |
||
75 | * @expectedException \Exception |
||
76 | */ |
||
77 | public function ensureGetIndexWithTooLongCollectionName() |
||
85 | |||
86 | /** |
||
87 | * @test |
||
88 | * @covers ::ensureGetIndex |
||
89 | * @expectedException \InvalidArgumentException |
||
90 | */ |
||
91 | public function ensureGetIndexWithNonStringBeforeSortKey() |
||
95 | |||
96 | /** |
||
97 | * @test |
||
98 | * @covers ::ensureGetIndex |
||
99 | * @expectedException \InvalidArgumentException |
||
100 | */ |
||
101 | public function ensureGetIndexWithNonStringAfterSortKey() |
||
105 | |||
106 | /** |
||
107 | * @test |
||
108 | * @covers ::ensureGetIndex |
||
109 | * @expectedException \InvalidArgumentException |
||
110 | */ |
||
111 | public function ensureGetIndexWithBadBeforeSortValue() |
||
115 | |||
116 | /** |
||
117 | * @test |
||
118 | * @covers ::ensureGetIndex |
||
119 | * @expectedException \InvalidArgumentException |
||
120 | */ |
||
121 | public function ensureGetIndexWithBadAfterSortValue() |
||
125 | |||
126 | /** |
||
127 | * Verifies the behaviour of the Queue when it cannot create an index after 5 attempts. |
||
128 | * |
||
129 | * @test |
||
130 | * @covers ::ensureGetIndex |
||
131 | * @expectedException \Exception |
||
132 | * @expectedExceptionMessage couldnt create index after 5 attempts |
||
133 | */ |
||
134 | public function ensureIndexCannotBeCreatedAfterFiveAttempts() |
||
143 | |||
144 | /** |
||
145 | * @test |
||
146 | * @covers ::ensureCountIndex |
||
147 | */ |
||
148 | public function ensureCountIndex() |
||
162 | |||
163 | /** |
||
164 | * @test |
||
165 | * @covers ::ensureCountIndex |
||
166 | */ |
||
167 | public function ensureCountIndexWithPrefixOfPrevious() |
||
178 | |||
179 | /** |
||
180 | * @test |
||
181 | * @covers ::ensureCountIndex |
||
182 | * @expectedException \InvalidArgumentException |
||
183 | */ |
||
184 | public function ensureCountIndexWithNonStringKey() |
||
188 | |||
189 | /** |
||
190 | * @test |
||
191 | * @covers ::ensureCountIndex |
||
192 | * @expectedException \InvalidArgumentException |
||
193 | */ |
||
194 | public function ensureCountIndexWithBadValue() |
||
198 | |||
199 | /** |
||
200 | * @test |
||
201 | * @covers ::get |
||
202 | */ |
||
203 | public function getByBadQuery() |
||
212 | |||
213 | /** |
||
214 | * @test |
||
215 | * @covers ::get |
||
216 | */ |
||
217 | public function getWithNegativePollDuration() |
||
222 | |||
223 | /** |
||
224 | * @test |
||
225 | * @covers ::get |
||
226 | * @expectedException \InvalidArgumentException |
||
227 | */ |
||
228 | public function getWithNonStringKey() |
||
232 | |||
233 | /** |
||
234 | * @test |
||
235 | * @covers ::get |
||
236 | */ |
||
237 | public function getByFullQuery() |
||
251 | |||
252 | /** |
||
253 | * @test |
||
254 | * @covers ::get |
||
255 | */ |
||
256 | public function getBySubDocQuery() |
||
275 | |||
276 | /** |
||
277 | * @test |
||
278 | * @covers ::get |
||
279 | */ |
||
280 | public function getBeforeAck() |
||
293 | |||
294 | /** |
||
295 | * @test |
||
296 | * @covers ::get |
||
297 | */ |
||
298 | public function getWithCustomPriority() |
||
316 | |||
317 | /** |
||
318 | * @test |
||
319 | * @covers ::get |
||
320 | */ |
||
321 | public function getWithTimeBasedPriority() |
||
339 | |||
340 | /** |
||
341 | * @test |
||
342 | * @covers ::get |
||
343 | */ |
||
344 | public function getWithTimeBasedPriorityWithOldTimestamp() |
||
366 | |||
367 | /** |
||
368 | * @test |
||
369 | * @covers ::get |
||
370 | */ |
||
371 | public function getWait() |
||
382 | |||
383 | /** |
||
384 | * @test |
||
385 | * @covers ::get |
||
386 | */ |
||
387 | public function earliestGet() |
||
399 | |||
400 | /** |
||
401 | * @test |
||
402 | * @covers ::get |
||
403 | */ |
||
404 | public function resetStuck() |
||
405 | { |
||
406 | $messageOne = ['key' => 0]; |
||
407 | $messageTwo = ['key' => 1]; |
||
408 | |||
409 | $this->queue->send($messageOne); |
||
410 | $this->queue->send($messageTwo); |
||
411 | |||
412 | //sets to running |
||
413 | $this->collection->updateOne( |
||
414 | ['payload.key' => 0], |
||
415 | ['$set' => ['earliestGet' => new \MongoDB\BSON\UTCDateTime(time() * 1000)]] |
||
416 | ); |
||
417 | $this->collection->updateOne( |
||
418 | ['payload.key' => 1], |
||
419 | ['$set' => ['earliestGet' => new \MongoDB\BSON\UTCDateTime(time() * 1000)]] |
||
420 | ); |
||
421 | |||
422 | $this->assertSame( |
||
423 | 2, |
||
424 | $this->collection->count( |
||
425 | ['earliestGet' => ['$lte' => new \MongoDB\BSON\UTCDateTime((int)(microtime(true) * 1000))]] |
||
426 | ) |
||
427 | ); |
||
428 | |||
429 | //resets and gets messageOne |
||
430 | $this->assertNotNull($this->queue->get($messageOne, PHP_INT_MAX, 0)); |
||
431 | |||
432 | $this->assertSame( |
||
433 | 1, |
||
434 | $this->collection->count( |
||
435 | ['earliestGet' => ['$lte' => new \MongoDB\BSON\UTCDateTime((int)(microtime(true) * 1000))]] |
||
436 | ) |
||
437 | ); |
||
438 | } |
||
439 | |||
440 | /** |
||
441 | * @test |
||
442 | * @covers ::count |
||
443 | * @expectedException \InvalidArgumentException |
||
444 | */ |
||
445 | public function countWithNonStringKey() |
||
446 | { |
||
447 | $this->queue->count([0 => 'a value']); |
||
448 | } |
||
449 | |||
450 | /** |
||
451 | * @test |
||
452 | * @covers ::count |
||
453 | */ |
||
454 | public function testCount() |
||
455 | { |
||
456 | $message = ['boo' => 'scary']; |
||
457 | |||
458 | $this->assertSame(0, $this->queue->count($message, true)); |
||
459 | $this->assertSame(0, $this->queue->count($message, false)); |
||
460 | $this->assertSame(0, $this->queue->count($message)); |
||
461 | |||
462 | $this->queue->send($message); |
||
463 | $this->assertSame(1, $this->queue->count($message, false)); |
||
464 | $this->assertSame(0, $this->queue->count($message, true)); |
||
465 | $this->assertSame(1, $this->queue->count($message)); |
||
466 | |||
467 | $this->queue->get($message, PHP_INT_MAX, 0); |
||
468 | $this->assertSame(0, $this->queue->count($message, false)); |
||
469 | $this->assertSame(1, $this->queue->count($message, true)); |
||
470 | $this->assertSame(1, $this->queue->count($message)); |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * @test |
||
475 | * @covers ::ack |
||
476 | */ |
||
477 | public function ack() |
||
490 | |||
491 | /** |
||
492 | * @test |
||
493 | * @covers ::ack |
||
494 | * @expectedException \InvalidArgumentException |
||
495 | */ |
||
496 | public function ackBadArg() |
||
500 | |||
501 | /** |
||
502 | * @test |
||
503 | * @covers ::ackSend |
||
504 | */ |
||
505 | public function ackSend() |
||
526 | |||
527 | /** |
||
528 | * Verify earliestGet with ackSend. |
||
529 | * |
||
530 | * @test |
||
531 | * @covers ::ackSend |
||
532 | * |
||
533 | * @return void |
||
534 | */ |
||
535 | public function ackSendWithEarliestGet() |
||
546 | |||
547 | /** |
||
548 | * @test |
||
549 | * @covers ::ackSend |
||
550 | * @expectedException \InvalidArgumentException |
||
551 | */ |
||
552 | public function ackSendWithWrongIdType() |
||
556 | |||
557 | /** |
||
558 | * @test |
||
559 | * @covers ::ackSend |
||
560 | * @expectedException \InvalidArgumentException |
||
561 | */ |
||
562 | public function ackSendWithNanPriority() |
||
566 | |||
567 | /** |
||
568 | * @test |
||
569 | * @covers ::ackSend |
||
570 | */ |
||
571 | public function ackSendWithHighEarliestGet() |
||
594 | |||
595 | /** |
||
596 | * @covers ::ackSend |
||
597 | */ |
||
598 | public function ackSendWithLowEarliestGet() |
||
624 | |||
625 | /** |
||
626 | * @test |
||
627 | * @covers ::requeue |
||
628 | */ |
||
629 | public function requeue() |
||
644 | |||
645 | /** |
||
646 | * @test |
||
647 | * @covers ::requeue |
||
648 | * @expectedException \InvalidArgumentException |
||
649 | */ |
||
650 | public function requeueBadArg() |
||
654 | |||
655 | /** |
||
656 | * @test |
||
657 | * @covers ::send |
||
658 | */ |
||
659 | public function send() |
||
680 | |||
681 | /** |
||
682 | * @test |
||
683 | * @covers ::send |
||
684 | * @expectedException \InvalidArgumentException |
||
685 | */ |
||
686 | public function sendWithNanPriority() |
||
690 | |||
691 | /** |
||
692 | * @test |
||
693 | * @covers ::send |
||
694 | */ |
||
695 | public function sendWithHighEarliestGet() |
||
715 | |||
716 | /** |
||
717 | * @test |
||
718 | * @covers ::send |
||
719 | */ |
||
720 | public function sendWithLowEarliestGet() |
||
740 | |||
741 | /** |
||
742 | * Verify Queue can be constructed with \MongoDB\Collection |
||
743 | * |
||
744 | * @test |
||
745 | * @covers ::__construct |
||
746 | * |
||
747 | * @return void |
||
748 | */ |
||
749 | public function constructWithCollection() |
||
781 | } |
||
782 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.