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

Testing Access Wrapper Laravel Package

wikimedia/testing-access-wrapper

Small PHP utility from Wikimedia that wraps objects to access otherwise non-public (protected/private) methods and properties in tests. Helps write focused unit tests without changing production visibility, acting as a thin “testing access wrapper.”

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require wikimedia/testing-access-wrapper
    

    No additional configuration is required for basic usage.

  2. First Use Case: Testing Private/Protected Methods The package provides a TestingAccessTrait to bypass visibility restrictions in unit tests.

    use Wikimedia\TestingAccessWrapper\TestingAccessTrait;
    
    class MyTest extends \PHPUnit\Framework\TestCase
    {
        use TestingAccessTrait;
    
        public function testPrivateMethod()
        {
            $object = new MyClass();
            $result = $this->callPrivateMethod($object, 'privateMethod', [$arg1, $arg2]);
            $this->assertEquals(expected, $result);
        }
    }
    
  3. Key Classes/Methods to Explore

    • TestingAccessTrait – Core trait for accessing private/protected methods.
    • callPrivateMethod() – Invokes a private method with arguments.
    • getPrivateProperty() – Accesses private/protected properties.
    • setPrivateProperty() – Modifies private/protected properties.

Implementation Patterns

Common Workflows

  1. Testing Legacy Code Use the trait to test methods marked as private or protected without refactoring:

    $this->callPrivateMethod($service, 'internalValidate', [$input]);
    
  2. Mocking Dependencies Override private properties to simulate dependency injection:

    $this->setPrivateProperty($repository, 'connection', $mockConnection);
    
  3. Integration with Laravel Combine with Laravel’s testing helpers (e.g., make:mock):

    $user = $this->callPrivateMethod($authManager, 'findUserByToken', [$token]);
    
  4. Dynamic Testing Use reflection-like access in tests without exposing internals:

    $value = $this->getPrivateProperty($model, 'hiddenField');
    

Integration Tips

  • Laravel Facades: Access private facade methods:
    $this->callPrivateMethod(\Illuminate\Support\Facades\Route::class, 'getRoutes', []);
    
  • Service Containers: Test container-bound singletons:
    $this->setPrivateProperty(app(), 'resolved', ['MyService' => $mock]);
    
  • Event Listeners: Inspect private event handlers:
    $this->callPrivateMethod($listener, 'handle', [$event]);
    

Gotchas and Tips

Pitfalls

  1. Reflection Overhead

    • The package uses PHP’s ReflectionClass, which can slow down tests.
    • Mitigation: Cache test results or avoid overusing in performance-critical tests.
  2. Breaking Encapsulation

    • Accessing private methods/properties violates OOP principles.
    • Mitigation: Refactor code to expose necessary interfaces instead of relying on this trait.
  3. Static Method Limitations

    • Cannot directly call static private methods via callPrivateMethod.
    • Workaround: Use callStaticMethod() (if available) or refactor to instance methods.
  4. Laravel-Specific Quirks

    • Some Laravel classes (e.g., Illuminate\Foundation\Application) may throw errors when accessing internals.
    • Tip: Test on a copy of the class or use partial mocking.

Debugging Tips

  • Verify Method/Property Names: Typos in method names will cause ReflectionException.
  • Check Visibility: Ensure the target method/property is private/protected (not public).
  • Use var_dump(): Debug property/method signatures:
    var_dump($this->getPrivateProperty($object, 'property'));
    

Extension Points

  1. Custom Accessors Extend the trait to add domain-specific helpers:

    trait MyTestingAccessTrait {
        use TestingAccessTrait;
    
        protected function callAdminMethod($object, $method, $args) {
            return $this->callPrivateMethod($object, $method, $args);
        }
    }
    
  2. Integration with Pest If using Pest, alias the trait for cleaner syntax:

    uses(TestingAccessTrait::class)->in('Tests');
    
  3. Logging Access Override methods to log accesses (useful for auditing):

    protected function callPrivateMethod($object, $method, $args) {
        \Log::debug("Accessing private method: {$method}");
        return parent::callPrivateMethod($object, $method, $args);
    }
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport