PHP: Testing Private and Protected Methods

A healthy goal for any application is 100% test coverage. Writing tests for private and protected methods in PHP can cause some issues because you can’t call these methods directly in the tests. Yet, they should be tested. Using reflection it’s possible test these methods. There are a couple ways to approach this.

While I’m assuming PHPUnit, these methods work outside of PHPUnit as well.

Testing A Single Method

Say, for example, you have the protected method baz on the class foo\bar and want to test the method. Here we can use ReflectionMethod to open up access.

public function testBaz() {
  
  // Grab ahold of the method and change its accessibility.
  $methd = new \ReflectionMethod('\foo\bar', 'baz');
  $method->setAccessible(true);

  $obj = new \foo\bar();
  $name = 'quz';
  $this->assertTrue($method->invoke($obj, $name));            
}

Testing Multiple Methods On A Class

There are times where you may want to test multiple methods on a class. For that you can use ReflectionClass.

function testStuff() {
  
  // Start by getting the class into reflection.
  $klass = new \ReflectionClass('\foo\bar');
  
  // Grab ahold of the first method and change its accessibility.
  $method = $klass->getMethod('baz');
  $method->setAccessible(true);

  $obj = new \foo\bar();
  $name = 'quz';
  $this->assertTrue($method->invoke($obj, $name));
  
  // Get a second method. This time pass in multiple arguments.
  $method = $klass->getMethod('quz');
  $method->setAccessible(true);
  $key = 'foo';
  $value = 'bar';
  $this->assertTrue($method->invoke($obj, $key, $value));
}

Using reflection in PHP we can easily write tests against the internals of our classes. This is important when trying to make sure everything keeps working.