Best practices to test protected methods with PHPUnit

There are a few ways you can test protected methods using PHPUnit:

  1. Use the setUp method to create a subclass of the class you want to test. You can then test the protected methods by calling them from the subclass.
<?php

class MyClassTest extends TestCase
{
  public function setUp()
  {
    $this->myClass = new class extends MyClass {
      public function callProtectedMethod()
      {
        return $this->protectedMethod();
      }
    };
  }

  public function testProtectedMethod()
  {
    $result = $this->myClass->callProtectedMethod();
    // Assert that $result is what you expect
  }
}

Watch a course Learn object oriented PHP

  1. Use the ReflectionClass class to create a new instance of the class and call the protected method using reflection.
<?php

class MyClassTest extends TestCase
{
  public function testProtectedMethod()
  {
    $reflection = new ReflectionClass(MyClass::class);
    $method = $reflection->getMethod('protectedMethod');
    $method->setAccessible(true);

    $myClass = new MyClass();
    $result = $method->invokeArgs($myClass, [
      /* any arguments */
    ]);
    // Assert that $result is what you expect
  }
}

It's generally not a good idea to test protected methods directly, as they are an implementation detail and are subject to change. Instead, you should focus on testing the public methods that use the protected methods, as they are the API that other code will use to interact with the class.