Weave 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

Php Expose Laravel Package

suin/php-expose

Expose helps PHPUnit tests access private/protected properties and methods in PHP objects. Use a simple fluent API to set non-public attributes and call hidden methods without changing production code. Requires PHP 5.3+ and installs via Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require suin/php-expose
    

    Ensure vendor/autoload.php is included in your PHPUnit bootstrap file (e.g., phpunit.xml):

    <php>
        <autoload>
            <file>vendor/autoload.php</file>
        </autoload>
    </php>
    
  2. First Use Case: Test a class with private/protected properties/methods. For example:

    use Expose\Expose as e;
    
    class User {
        private $name;
        protected $email;
    
        private function validateEmail() { ... }
    }
    
    $user = new User();
    $user->name = 'John'; // Normally inaccessible
    
    // Expose and test
    e::expose($user)
        ->attr('name', 'John') // Set private property
        ->attr('email', '[email protected]'); // Set protected property
    
    $result = e::expose($user)->call('validateEmail'); // Call private method
    

Implementation Patterns

Workflows

  1. Property Access:

    • Use Expose::expose($object)->attr('property', $value) to set/get private/protected properties.
    • Chain calls for multiple properties:
      e::expose($user)
          ->attr('name', 'Alice')
          ->attr('email', '[email protected]');
      
  2. Method Invocation:

    • Call private/protected methods with Expose::expose($object)->call('method', $arg1, $arg2).
    • Example:
      $validationResult = e::expose($user)->call('validateEmail');
      
  3. Test Setup:

    • Use in setUp() to initialize test objects with default values:
      public function setUp(): void {
          $this->user = new User();
          e::expose($this->user)
              ->attr('name', 'Test User')
              ->attr('email', '[email protected]');
      }
      
  4. Assertions:

    • Combine with PHPUnit assertions:
      $this->assertEquals('Test User', e::expose($this->user)->attr('name'));
      

Integration Tips

  • Mocking: Use alongside PHPUnit mocks for complex scenarios:
    $mock = $this->getMockBuilder(User::class)->disableOriginalConstructor()->getMock();
    e::expose($mock)->call('privateMethod');
    
  • Data Factories: Pre-configure exposed properties in factories for reusable test data.
  • Traits: Extend Expose functionality in custom traits for project-specific needs.

Gotchas and Tips

Pitfalls

  1. Visibility Leakage:

    • Exposing properties/methods bypasses encapsulation. Use sparingly—prefer refactoring to expose only what’s necessary for tests.
    • Example: Avoid exposing sensitive data (e.g., passwords) even in tests.
  2. Static Methods:

    • Expose does not handle static private/protected members. Use reflection directly if needed:
      $reflection = new ReflectionClass(User::class);
      $method = $reflection->getMethod('_staticMethod');
      $method->setAccessible(true);
      $method->invoke(null, $arg);
      
  3. Performance:

    • Avoid exposing in production code or performance-critical paths. The package is purely for testing.
  4. PHPUnit Integration:

    • Ensure Expose is loaded before tests run (via bootstrap.php in phpunit.xml). Failure to do so may result in undefined class errors.

Debugging

  • Undefined Property/Method:

    • Verify property/method names match exactly (including case and underscores).
    • Check for typos in Expose::expose($object)->attr('property') or ->call('method').
  • Reflection Errors:

    • If Expose fails silently, enable PHP error reporting or wrap calls in try-catch:
      try {
          e::expose($user)->call('nonexistentMethod');
      } catch (\Exception $e) {
          $this->fail("Method call failed: " . $e->getMessage());
      }
      

Tips

  1. Selective Exposure:

    • Use Expose only for properties/methods that are genuinely needed in tests. Document why each is exposed.
  2. Custom Expose Classes:

    • Extend Expose for project-specific needs:
      class CustomExpose extends \Expose\Expose {
          public function exposeStatic($class, $method, ...$args) {
              $reflection = new ReflectionMethod($class, $method);
              $reflection->setAccessible(true);
              return $reflection->invokeArgs(null, $args);
          }
      }
      
  3. IDE Support:

    • Modern IDEs (e.g., PHPStorm) may not recognize Expose calls. Use @method or @property annotations in test classes to improve autocompletion:
      /**
       * @property string $name
       * @method string _privateMethod()
       */
      class UserTest extends \PHPUnit\Framework\TestCase { ... }
      
  4. Alternatives:

    • For complex scenarios, consider:
      • PHPUnit’s ReflectionClass: More control but verbose.
      • Mockery: For mocking private methods without exposing.
      • Laravel’s Artisan::call(): For testing commands with private methods (if using Laravel).
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels