phrity/net-mock
Mocking layer for phrity/net-stream to simplify testing stream-based code. Drop-in compatible stream classes that can log all interactions via any PSR-3 logger and override behavior with callbacks. Includes PHPUnit expectation traits for asserting calls and parameters.
Install the package:
composer require phrity/net-mock
Replace real stream factory with mock in tests:
use Phrity\Net\Mock\StreamFactory;
// In your test setup
$this->app->bind(\Phrity\Net\StreamFactory::class, function () {
return new StreamFactory(); // Mock factory
});
First use case: Verify stream writes
use Phrity\Net\Mock\ExpectSocketStreamTrait;
class MyTest extends TestCase {
use ExpectSocketStreamTrait;
public function testStreamWrite() {
$this->expectSocketStreamWrite()
->addAssert(function (string $method, array $params) {
$this->assertEquals('test data', $params[0]);
});
$stream = new SocketStream($resource);
$stream->write('test data');
}
}
ExpectSocketStreamTrait, ExpectContextTrait, etc., for available expectations.Phrity\Net\Mock\Mock for global callbacks/logging.Dependency Injection
// In Laravel service provider
$this->app->when(\Your\StreamUsingClass::class)
->needs(\Phrity\Net\StreamFactory::class)
->give(function () {
return config('app.env') === 'testing'
? new \Phrity\Net\Mock\StreamFactory()
: new \Phrity\Net\RealStreamFactory();
});
Logging Interactions
use Phrity\Net\Mock\Mock;
use Monolog\Logger;
$logger = new Logger('stream_mock');
Mock::setLogger($logger);
// All stream calls will log to Monolog
Callback-Based Mocking
Mock::setCallback(function ($counter, $method, $params, $default) {
if ($method === 'write') {
$this->assertEquals('expected', $params[0]);
return true; // Simulate success
}
return $default($params); // Fallback to real implementation
});
Expectation Stack in Tests
use Phrity\Net\Mock\ExpectSocketStreamTrait;
class MyTest {
use ExpectSocketStreamTrait;
public function testComplexScenario() {
$this->expectSocketStreamWrite()
->times(3)
->addAssert(function ($method, $params) {
$this->assertStringStartsWith('prefix', $params[0]);
});
$this->expectSocketStreamClose()->setReturn(true);
}
}
Test-Driven Development (TDD)
Debugging Production Issues
Mock::setLogger(new \Monolog\Logger('stream_debug'));
Integration Testing
config/testing.php:
'stream_mock' => [
'enabled' => env('STREAM_MOCK_ENABLED', false),
'logger' => \Phrity\Net\Mock\EchoLogger::class,
],
Expectation Leaks
tearDownStack() causes tests to fail silently.setUp()/tearDown() in test classes.Version Mismatches
net-mock@2.4 requires net-stream@2.4. Always align versions.composer require phrity/net-stream:^2.4 alongside the mock.Stateful Streams
Global Callbacks
Mock::setCallback() affects all tests. Overwrite carefully.setUp()/tearDown().PHP 8.1+ Requirement
Enable Logging
Mock::setLogger(new \Phrity\Net\Mock\EchoLogger());
Outputs all method calls to stderr.
Inspect Stack
$stack = Mock::getStack();
print_r($stack->getExpectations());
Fallback to Real Implementation
Use $default in callbacks to debug real behavior:
Mock::setCallback(function ($counter, $method, $params, $default) {
return $default($params); // Bypass mock
});
Partial Mocking Mock only specific methods:
$this->expectSocketStreamWrite()->setReturn(true);
// Other methods use real implementation
Dynamic Returns
$this->expectSocketStreamRead()->setReturn(function () {
return 'dynamic_' . time();
});
Laravel Facades
Create a facade for Mock to simplify usage:
// app/Facades/StreamMock.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class StreamMock extends Facade {
protected static function getFacadeAccessor() {
return 'stream.mock';
}
}
Performance
if (app()->environment('production')) {
$factory = new \Phrity\Net\RealStreamFactory();
}
Extending Mocks Create custom traits for domain-specific expectations:
trait ExpectCustomStreamTrait {
public function expectCustomStream() {
return $this->expect('customStream', 'method');
}
}
CI/CD Optimization
.github/workflows/test.yml:
steps:
- run: composer require phrity/net-mock
- run: php artisan test --env=testing
How can I help you explore Laravel packages today?