Skip to content

Commit caabd13

Browse files
committed
Use ConnectionInterface intsead of partial mocks
1 parent 838e284 commit caabd13

File tree

2 files changed

+135
-47
lines changed

2 files changed

+135
-47
lines changed

tests/FactoryStreamingClientTest.php

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,45 @@ public function testWillWriteAuthCommandIfRedisUnixUriContainsUserInfo()
136136

137137
public function testWillResolveWhenAuthCommandReceivesOkResponseIfRedisUriContainsUserInfo()
138138
{
139-
$stream = $this->createCallableMockWithOriginalConstructorDisabled(array('write'));
139+
$dataHandler = null;
140+
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
140141
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
142+
$stream->expects($this->exactly(2))->method('on')->withConsecutive(
143+
array('data', $this->callback(function ($arg) use (&$dataHandler) {
144+
$dataHandler = $arg;
145+
return true;
146+
})),
147+
array('close', $this->anything())
148+
);
141149

142150
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
143151
$promise = $this->factory->createClient('redis://:world@localhost');
144152

145-
$stream->emit('data', array("+OK\r\n"));
153+
$this->assertTrue(is_callable($dataHandler));
154+
$dataHandler("+OK\r\n");
146155

147156
$promise->then($this->expectCallableOnceWith($this->isInstanceOf('Clue\React\Redis\Client')));
148157
}
149158

150159
public function testWillRejectAndCloseAutomaticallyWhenAuthCommandReceivesErrorResponseIfRedisUriContainsUserInfo()
151160
{
152-
$stream = $this->createCallableMockWithOriginalConstructorDisabled(array('write', 'close'));
161+
$dataHandler = null;
162+
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
153163
$stream->expects($this->once())->method('write')->with("*2\r\n$4\r\nauth\r\n$5\r\nworld\r\n");
154164
$stream->expects($this->once())->method('close');
165+
$stream->expects($this->exactly(2))->method('on')->withConsecutive(
166+
array('data', $this->callback(function ($arg) use (&$dataHandler) {
167+
$dataHandler = $arg;
168+
return true;
169+
})),
170+
array('close', $this->anything())
171+
);
155172

156173
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
157174
$promise = $this->factory->createClient('redis://:world@localhost');
158175

159-
$stream->emit('data', array("-ERR invalid password\r\n"));
176+
$this->assertTrue(is_callable($dataHandler));
177+
$dataHandler("-ERR invalid password\r\n");
160178

161179
$promise->then(null, $this->expectCallableOnceWith(
162180
$this->logicalAnd(
@@ -182,27 +200,45 @@ public function testWillWriteSelectCommandIfRedisUnixUriContainsDbQueryParameter
182200

183201
public function testWillResolveWhenSelectCommandReceivesOkResponseIfRedisUriContainsPath()
184202
{
185-
$stream = $this->createCallableMockWithOriginalConstructorDisabled(array('write'));
203+
$dataHandler = null;
204+
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
186205
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$3\r\n123\r\n");
206+
$stream->expects($this->exactly(2))->method('on')->withConsecutive(
207+
array('data', $this->callback(function ($arg) use (&$dataHandler) {
208+
$dataHandler = $arg;
209+
return true;
210+
})),
211+
array('close', $this->anything())
212+
);
187213

188214
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
189215
$promise = $this->factory->createClient('redis://localhost/123');
190216

191-
$stream->emit('data', array("+OK\r\n"));
217+
$this->assertTrue(is_callable($dataHandler));
218+
$dataHandler("+OK\r\n");
192219

193220
$promise->then($this->expectCallableOnceWith($this->isInstanceOf('Clue\React\Redis\Client')));
194221
}
195222

196223
public function testWillRejectAndCloseAutomaticallyWhenSelectCommandReceivesErrorResponseIfRedisUriContainsPath()
197224
{
198-
$stream = $this->createCallableMockWithOriginalConstructorDisabled(array('write', 'close'));
225+
$dataHandler = null;
226+
$stream = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
199227
$stream->expects($this->once())->method('write')->with("*2\r\n$6\r\nselect\r\n$3\r\n123\r\n");
200228
$stream->expects($this->once())->method('close');
229+
$stream->expects($this->exactly(2))->method('on')->withConsecutive(
230+
array('data', $this->callback(function ($arg) use (&$dataHandler) {
231+
$dataHandler = $arg;
232+
return true;
233+
})),
234+
array('close', $this->anything())
235+
);
201236

202237
$this->connector->expects($this->once())->method('connect')->willReturn(Promise\resolve($stream));
203238
$promise = $this->factory->createClient('redis://localhost/123');
204239

205-
$stream->emit('data', array("-ERR DB index is out of range\r\n"));
240+
$this->assertTrue(is_callable($dataHandler));
241+
$dataHandler("-ERR DB index is out of range\r\n");
206242

207243
$promise->then(null, $this->expectCallableOnceWith(
208244
$this->logicalAnd(
@@ -337,15 +373,4 @@ public function testCreateClientWithoutTimeoutParameterWillStartTimerWithDefault
337373
$this->factory->createClient('redis://127.0.0.1:2');
338374
ini_set('default_socket_timeout', $old);
339375
}
340-
341-
public function createCallableMockWithOriginalConstructorDisabled($array)
342-
{
343-
if (method_exists('PHPUnit\Framework\MockObject\MockBuilder', 'addMethods')) {
344-
// PHPUnit 9+
345-
return $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->onlyMethods($array)->getMock();
346-
} else {
347-
// legacy PHPUnit 4 - PHPUnit 8
348-
return $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->setMethods($array)->getMock();
349-
}
350-
}
351376
}

tests/LazyClientTest.php

Lines changed: 91 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,24 @@ public function testPingAfterPreviousFactoryRejectsUnderlyingClientWillCreateNew
156156

157157
public function testPingAfterPreviousUnderlyingClientAlreadyClosedWillCreateNewUnderlyingConnection()
158158
{
159-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
159+
$closeHandler = null;
160+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
160161
$client->expects($this->once())->method('__call')->with('ping')->willReturn(\React\Promise\resolve('PONG'));
162+
$client->expects($this->any())->method('on')->withConsecutive(
163+
array('close', $this->callback(function ($arg) use (&$closeHandler) {
164+
$closeHandler = $arg;
165+
return true;
166+
}))
167+
);
161168

162169
$this->factory->expects($this->exactly(2))->method('createClient')->willReturnOnConsecutiveCalls(
163170
\React\Promise\resolve($client),
164171
new Promise(function () { })
165172
);
166173

167174
$this->client->ping();
168-
$client->emit('close');
175+
$this->assertTrue(is_callable($closeHandler));
176+
$closeHandler();
169177

170178
$this->client->ping();
171179
}
@@ -183,7 +191,7 @@ public function testPingAfterCloseWillRejectWithoutCreatingUnderlyingConnection(
183191
public function testPingAfterPingWillNotStartIdleTimerWhenFirstPingResolves()
184192
{
185193
$deferred = new Deferred();
186-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
194+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
187195
$client->expects($this->exactly(2))->method('__call')->willReturnOnConsecutiveCalls(
188196
$deferred->promise(),
189197
new Promise(function () { })
@@ -201,7 +209,7 @@ public function testPingAfterPingWillNotStartIdleTimerWhenFirstPingResolves()
201209
public function testPingAfterPingWillStartAndCancelIdleTimerWhenSecondPingStartsAfterFirstResolves()
202210
{
203211
$deferred = new Deferred();
204-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
212+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
205213
$client->expects($this->exactly(2))->method('__call')->willReturnOnConsecutiveCalls(
206214
$deferred->promise(),
207215
new Promise(function () { })
@@ -220,7 +228,7 @@ public function testPingAfterPingWillStartAndCancelIdleTimerWhenSecondPingStarts
220228

221229
public function testPingFollowedByIdleTimerWillCloseUnderlyingConnectionWithoutCloseEvent()
222230
{
223-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call', 'close'));
231+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
224232
$client->expects($this->once())->method('__call')->willReturn(\React\Promise\resolve());
225233
$client->expects($this->once())->method('close')->willReturn(\React\Promise\resolve());
226234

@@ -298,7 +306,7 @@ public function testCloseAfterPingWillCloseUnderlyingClientConnectionWhenAlready
298306
public function testCloseAfterPingWillCancelIdleTimerWhenPingIsAlreadyResolved()
299307
{
300308
$deferred = new Deferred();
301-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call', 'close'));
309+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
302310
$client->expects($this->once())->method('__call')->willReturn($deferred->promise());
303311
$client->expects($this->once())->method('close');
304312

@@ -316,7 +324,7 @@ public function testCloseAfterPingWillCancelIdleTimerWhenPingIsAlreadyResolved()
316324
public function testCloseAfterPingRejectsWillEmitClose()
317325
{
318326
$deferred = new Deferred();
319-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call', 'close'));
327+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
320328
$client->expects($this->once())->method('__call')->willReturn($deferred->promise());
321329
$client->expects($this->once())->method('close')->willReturnCallback(function () use ($client) {
322330
$client->emit('close');
@@ -358,9 +366,15 @@ public function testEndAfterPingWillEndUnderlyingClient()
358366

359367
public function testEndAfterPingWillCloseClientWhenUnderlyingClientEmitsClose()
360368
{
361-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call', 'end'));
369+
$closeHandler = null;
370+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
362371
$client->expects($this->once())->method('__call')->with('ping')->willReturn(\React\Promise\resolve('PONG'));
363372
$client->expects($this->once())->method('end');
373+
$client->expects($this->any())->method('on')->willReturnCallback(function ($event, $callback) use (&$closeHandler) {
374+
if ($event === 'close') {
375+
$closeHandler = $callback;
376+
}
377+
});
364378

365379
$deferred = new Deferred();
366380
$this->factory->expects($this->once())->method('createClient')->willReturn($deferred->promise());
@@ -371,14 +385,15 @@ public function testEndAfterPingWillCloseClientWhenUnderlyingClientEmitsClose()
371385
$this->client->on('close', $this->expectCallableOnce());
372386
$this->client->end();
373387

374-
$client->emit('close');
388+
$this->assertTrue(is_callable($closeHandler));
389+
$closeHandler();
375390
}
376391

377392
public function testEmitsNoErrorEventWhenUnderlyingClientEmitsError()
378393
{
379394
$error = new \RuntimeException();
380395

381-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
396+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
382397
$client->expects($this->once())->method('__call')->willReturn(\React\Promise\resolve());
383398

384399
$deferred = new Deferred();
@@ -393,7 +408,7 @@ public function testEmitsNoErrorEventWhenUnderlyingClientEmitsError()
393408

394409
public function testEmitsNoCloseEventWhenUnderlyingClientEmitsClose()
395410
{
396-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
411+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
397412
$client->expects($this->once())->method('__call')->willReturn(\React\Promise\resolve());
398413

399414
$deferred = new Deferred();
@@ -408,9 +423,16 @@ public function testEmitsNoCloseEventWhenUnderlyingClientEmitsClose()
408423

409424
public function testEmitsNoCloseEventButWillCancelIdleTimerWhenUnderlyingConnectionEmitsCloseAfterPingIsAlreadyResolved()
410425
{
426+
$closeHandler = null;
427+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
411428
$deferred = new Deferred();
412-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
413429
$client->expects($this->once())->method('__call')->willReturn($deferred->promise());
430+
$client->expects($this->any())->method('on')->withConsecutive(
431+
array('close', $this->callback(function ($arg) use (&$closeHandler) {
432+
$closeHandler = $arg;
433+
return true;
434+
}))
435+
);
414436

415437
$this->factory->expects($this->once())->method('createClient')->willReturn(\React\Promise\resolve($client));
416438

@@ -423,13 +445,20 @@ public function testEmitsNoCloseEventButWillCancelIdleTimerWhenUnderlyingConnect
423445
$this->client->ping();
424446
$deferred->resolve();
425447

426-
$client->emit('close');
448+
$this->assertTrue(is_callable($closeHandler));
449+
$closeHandler();
427450
}
428451

429452
public function testEmitsMessageEventWhenUnderlyingClientEmitsMessageForPubSubChannel()
430453
{
431-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
454+
$messageHandler = null;
455+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
432456
$client->expects($this->once())->method('__call')->willReturn(\React\Promise\resolve());
457+
$client->expects($this->any())->method('on')->willReturnCallback(function ($event, $callback) use (&$messageHandler) {
458+
if ($event === 'message') {
459+
$messageHandler = $callback;
460+
}
461+
});
433462

434463
$deferred = new Deferred();
435464
$this->factory->expects($this->once())->method('createClient')->willReturn($deferred->promise());
@@ -438,74 +467,108 @@ public function testEmitsMessageEventWhenUnderlyingClientEmitsMessageForPubSubCh
438467
$deferred->resolve($client);
439468

440469
$this->client->on('message', $this->expectCallableOnce());
441-
$client->emit('message', array('foo', 'bar'));
470+
$this->assertTrue(is_callable($messageHandler));
471+
$messageHandler('foo', 'bar');
442472
}
443473

444474
public function testEmitsUnsubscribeAndPunsubscribeEventsWhenUnderlyingClientClosesWhileUsingPubSubChannel()
445475
{
446-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
476+
$allHandler = null;
477+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
447478
$client->expects($this->exactly(6))->method('__call')->willReturn(\React\Promise\resolve());
479+
$client->expects($this->any())->method('on')->willReturnCallback(function ($event, $callback) use (&$allHandler) {
480+
if (!isset($allHandler[$event])) {
481+
$allHandler[$event] = $callback;
482+
}
483+
});
448484

449485
$this->factory->expects($this->once())->method('createClient')->willReturn(\React\Promise\resolve($client));
450486

451487
$this->client->subscribe('foo');
452-
$client->emit('subscribe', array('foo', 1));
488+
$this->assertTrue(is_callable($allHandler['subscribe']));
489+
$allHandler['subscribe']('foo', 1);
453490

454491
$this->client->subscribe('bar');
455-
$client->emit('subscribe', array('bar', 2));
492+
$this->assertTrue(is_callable($allHandler['subscribe']));
493+
$allHandler['subscribe']('bar', 2);
456494

457495
$this->client->unsubscribe('bar');
458-
$client->emit('unsubscribe', array('bar', 1));
496+
$this->assertTrue(is_callable($allHandler['unsubscribe']));
497+
$allHandler['unsubscribe']('bar', 1);
459498

460499
$this->client->psubscribe('foo*');
461-
$client->emit('psubscribe', array('foo*', 1));
500+
$this->assertTrue(is_callable($allHandler['psubscribe']));
501+
$allHandler['psubscribe']('foo*', 1);
462502

463503
$this->client->psubscribe('bar*');
464-
$client->emit('psubscribe', array('bar*', 2));
504+
$this->assertTrue(is_callable($allHandler['psubscribe']));
505+
$allHandler['psubscribe']('bar*', 2);
465506

466507
$this->client->punsubscribe('bar*');
467-
$client->emit('punsubscribe', array('bar*', 1));
508+
$this->assertTrue(is_callable($allHandler['punsubscribe']));
509+
$allHandler['punsubscribe']('bar*', 1);
468510

469511
$this->client->on('unsubscribe', $this->expectCallableOnce());
470512
$this->client->on('punsubscribe', $this->expectCallableOnce());
471-
$client->emit('close');
513+
514+
$this->assertTrue(is_callable($allHandler['close']));
515+
$allHandler['close']();
472516
}
473517

474518
public function testSubscribeWillResolveWhenUnderlyingClientResolvesSubscribeAndNotStartIdleTimerWithIdleDueToSubscription()
475519
{
520+
$subscribeHandler = null;
476521
$deferred = new Deferred();
477-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
522+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
478523
$client->expects($this->once())->method('__call')->with('subscribe')->willReturn($deferred->promise());
524+
$client->expects($this->any())->method('on')->willReturnCallback(function ($event, $callback) use (&$subscribeHandler) {
525+
if ($event === 'subscribe' && $subscribeHandler === null) {
526+
$subscribeHandler = $callback;
527+
}
528+
});
479529

480530
$this->factory->expects($this->once())->method('createClient')->willReturn(\React\Promise\resolve($client));
481531

482532
$this->loop->expects($this->never())->method('addTimer');
483533

484534
$promise = $this->client->subscribe('foo');
485-
$client->emit('subscribe', array('foo', 1));
535+
$this->assertTrue(is_callable($subscribeHandler));
536+
$subscribeHandler('foo', 1);
486537
$deferred->resolve(array('subscribe', 'foo', 1));
487538

488539
$promise->then($this->expectCallableOnceWith(array('subscribe', 'foo', 1)));
489540
}
490541

491542
public function testUnsubscribeAfterSubscribeWillResolveWhenUnderlyingClientResolvesUnsubscribeAndStartIdleTimerWhenSubscriptionStopped()
492543
{
544+
$subscribeHandler = null;
545+
$unsubscribeHandler = null;
493546
$deferredSubscribe = new Deferred();
494547
$deferredUnsubscribe = new Deferred();
495-
$client = $this->createCallableMockWithOriginalConstructorDisabled(array('__call'));
548+
$client = $this->getMockBuilder('Clue\React\Redis\Client')->getMock();
496549
$client->expects($this->exactly(2))->method('__call')->willReturnOnConsecutiveCalls($deferredSubscribe->promise(), $deferredUnsubscribe->promise());
550+
$client->expects($this->any())->method('on')->willReturnCallback(function ($event, $callback) use (&$subscribeHandler, &$unsubscribeHandler) {
551+
if ($event === 'subscribe' && $subscribeHandler === null) {
552+
$subscribeHandler = $callback;
553+
}
554+
if ($event === 'unsubscribe' && $unsubscribeHandler === null) {
555+
$unsubscribeHandler = $callback;
556+
}
557+
});
497558

498559
$this->factory->expects($this->once())->method('createClient')->willReturn(\React\Promise\resolve($client));
499560

500561
$this->loop->expects($this->once())->method('addTimer');
501562

502563
$promise = $this->client->subscribe('foo');
503-
$client->emit('subscribe', array('foo', 1));
564+
$this->assertTrue(is_callable($subscribeHandler));
565+
$subscribeHandler('foo', 1);
504566
$deferredSubscribe->resolve(array('subscribe', 'foo', 1));
505567
$promise->then($this->expectCallableOnceWith(array('subscribe', 'foo', 1)));
506568

507569
$promise = $this->client->unsubscribe('foo');
508-
$client->emit('unsubscribe', array('foo', 0));
570+
$this->assertTrue(is_callable($unsubscribeHandler));
571+
$unsubscribeHandler('foo', 0);
509572
$deferredUnsubscribe->resolve(array('unsubscribe', 'foo', 0));
510573
$promise->then($this->expectCallableOnceWith(array('unsubscribe', 'foo', 0)));
511574
}

0 commit comments

Comments
 (0)