Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Net Mock Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Mocking Paradigm Alignment: The package adheres to behavioral mocking principles, which aligns with Laravel’s emphasis on testability and dependency injection. The dual-mode (real/mock) factory pattern is a clean fit for Laravel’s service container, enabling environment-aware testing.
  • Stream Abstraction: Targets phrity/net-stream, a low-level networking library, which is often used in Laravel for custom HTTP clients, WebSocket handlers, or file I/O wrappers. The mock layer abstracts away real I/O, making it ideal for unit/integration testing of these components.
  • PSR Compliance: Leverages PSR-3 logging and PSR-15 middleware-like callbacks, ensuring compatibility with Laravel’s logging stack (Monolog) and middleware pipeline.
  • Test-Driven Design (TDD) Support: The expectation stack and trait-based assertions reduce boilerplate, accelerating TDD for stateful stream operations (e.g., verifying a socket writes data in a specific sequence before closing).

Integration Feasibility

  • Laravel Service Container:
    • Interface Binding: Define StreamFactoryInterface and bind RealStreamFactory (production) and MockStreamFactory (tests) to the same interface. Use contextual binding (e.g., app()->bindWhen(...)) or environment-based resolution (e.g., config('app.env') === 'testing').
    • Test Helpers: Create a test helper trait (e.g., uses(PhrityMocks::class)) to auto-configure mocks for all test classes.
  • Dependency Injection:
    • Constructor Injection: Ensure classes using phrity/net-stream accept StreamFactoryInterface via constructor. If not, use method injection or setters (as shown in the README).
    • Facade Pattern: If the codebase uses facades (e.g., Stream::socket()), refactor to inject the factory or create a testing facade that delegates to the mock.
  • Configuration:
    • Environment Variables: Toggle mocks via .env (e.g., STREAM_MOCK=true).
    • Pest/PHPUnit Extensions: Integrate with Pest’s beforeEach or PHPUnit’s setUp() to auto-initialize mocks.

Technical Risk

  • Version Synchronization:
    • Hard Dependency: phrity/net-mock must match phrity/net-stream versions. Risk: Future breaking changes in net-stream may require urgent updates to net-mock.
    • Mitigation: Pin versions in composer.json and monitor GitHub releases for net-stream.
  • Testing Complexity:
    • Stateful Streams: Mocking asynchronous or multi-call streams (e.g., TCP handshakes) may require complex callbacks, increasing test fragility.
    • Expectation Management: Forgetting to reset the mock stack (tearDownStack()) can lead to flaky tests across test suites.
  • Performance Overhead:
    • Mock Layer Overhead: Mocks introduce indirection, which may slow down performance-critical tests. Measure impact in CI/CD pipelines.
  • Limited Ecosystem:
    • No Dependents: Unproven in production; risk of undiscovered edge cases (e.g., SSL streams, custom stream types).
    • Documentation Gaps: Lack of real-world examples (e.g., mocking WebSocket streams) may require internal documentation.

Key Questions

  1. Current Stream Usage:
    • Which Laravel components (e.g., HTTP clients, file uploads, custom protocols) use phrity/net-stream? Prioritize mocking for high-risk, flaky tests.
  2. Testing Strategy:
    • Will mocks replace real I/O entirely, or will they coexist (e.g., mock for unit tests, real I/O for integration tests)?
  3. Versioning Policy:
    • How will the team sync net-mock and net-stream versions? Will a composer script or CI check enforce compatibility?
  4. Failure Modes:
    • What happens if a mock expectation fails in a long-running test suite? Will tests fail fast or silently proceed?
  5. Maintenance Burden:
    • Who will update mocks if phrity/net-stream adds new methods? Is there a backward-compatibility guarantee from the package maintainers?
  6. Alternatives:
    • Could native PHPUnit mocks or Mockery achieve the same goals with less coupling to phrity/net-stream?

Integration Approach

Stack Fit

  • Laravel Service Container:
    • Interface-Driven: Define StreamFactoryInterface and bind implementations:
      // app/Providers/AppServiceProvider.php
      public function register()
      {
          $this->app->bind(StreamFactoryInterface::class, function ($app) {
              return config('app.env') === 'testing'
                  ? new MockStreamFactory()
                  : new RealStreamFactory();
          });
      }
      
    • Contextual Binding: Use Laravel’s contextual binding to resolve mocks only in tests:
      $this->app->bindWhen(
          StreamFactoryInterface::class,
          fn () => true,
          fn () => new MockStreamFactory()
      );
      
  • Testing Frameworks:
    • Pest: Auto-initialize mocks in PestTestCase:
      use Phrity\Net\Mock\Mock;
      
      beforeEach(function () {
          Mock::setLogger(new EchoLogger());
          Mock::setCallback(fn ($counter, $method, $params, $default) => $default($params));
      });
      
    • PHPUnit: Use traits for expectation assertions:
      use Phrity\Net\Mock\ExpectSocketStreamTrait;
      
      class MyTest extends TestCase
      {
          use ExpectSocketStreamTrait;
      
          public function testStreamWrite()
          {
              $this->expectSocketStreamWrite()->addAssert(fn ($method, $params) =>
                  $this->assertEquals('data', $params[0])
              );
              // Test code...
          }
      }
      
  • Logging Integration:
    • Monolog: Configure EchoLogger to write to Laravel’s log channel:
      Mock::setLogger(new class implements LoggerInterface {
          public function log($level, $message, array $context = []): void
          {
              Log::channel('single')->info($message, $context);
          }
      });
      

Migration Path

  1. Assessment Phase:
    • Audit the codebase for classes using phrity/net-stream.
    • Identify high-priority components (e.g., flaky tests, critical features).
  2. Dependency Injection:
    • Refactor hardcoded stream usage to accept StreamFactoryInterface.
    • Example:
      // Before
      $stream = new SocketStream(stream_socket_client(...));
      
      // After
      $stream = $this->streamFactory->createSocketStream(...);
      
  3. Testing Infrastructure:
    • Add test helpers to auto-configure mocks (e.g., Pest extensions).
    • Example:
      // tests/TestCase.php
      use Phrity\Net\Mock\Mock;
      
      abstract class TestCase extends PestTestCase
      {
          protected function setUp(): void
          {
              Mock::setLogger(new EchoLogger());
              parent::setUp();
          }
      }
      
  4. Gradual Rollout:
    • Start with unit tests, then expand to integration tests.
    • Replace real I/O tests with mocks where deterministic behavior is critical.

Compatibility

  • Laravel Versions:
    • PHP 8.1+: Required by net-mock@2.x. Ensure compatibility with Laravel 9+.
    • Legacy Support: For Laravel 8.0, use net-mock@1.x (PHP 7.4).
  • Third-Party Libraries:
    • Guzzle HTTP Client: If used with phrity/net-stream, ensure no conflicts in stream handling.
    • ReactPHP: If the app uses reactive streams, evaluate whether net-mock can coexist or if a hybrid approach is needed.
  • Custom Stream Types:
    • The package supports core phrity/net-stream classes (e.g., SocketStream, Context). Custom stream types may require additional mock implementations.

Sequencing

  1. Phase 1: Setup
    • Add phrity/net-mock to composer.json.
    • Define StreamFactoryInterface and bind implementations.
  2. Phase 2: Refactoring
    • Inject StreamFactoryInterface into stream-using classes.
    • Update constructors/setters to
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony