Current Location: Home> Latest Articles> Verify mock type using is_a() in automated testing

Verify mock type using is_a() in automated testing

M66 2025-06-05

In automated testing, mock (mock object) is one of our commonly used testing techniques. It allows us to isolate test targets and avoid dependence on external systems or complex object interactions. When using mock, a common requirement is to confirm whether the mock object is an instance of a certain class or interface. At this time, the is_a() function provided by PHP is very useful.

What is is_a() ?

is_a() is a built-in function in PHP, which is used to determine whether an object is an instance of a certain class, or whether an interface is implemented. Its basic syntax is as follows:

 bool is_a(object|string $object_or_class, string $class, bool $allow_string = false)
  • $object_or_class : The object or class name to be checked.

  • $class : The class or interface name to be checked.

  • $allow_string : Whether to allow string class name as the first parameter. PHP 8.0 and later is false by default.

Using mock in automated testing

Let's use PHPUnit as an example to illustrate how to use is_a() to determine the type of a mock object. In PHPUnit, objects created with $this->createMock() are simulated, but they still retain their original type inheritance or interface implementation relationship by default.

Sample code

Suppose we have the following interface and implementation:

 interface LoggerInterface {
    public function log(string $message);
}

class FileLogger implements LoggerInterface {
    public function log(string $message) {
        // Write to log files
    }
}

In our test, we need to use a mock object instead of the real FileLogger :

 use PHPUnit\Framework\TestCase;

class SomeTest extends TestCase {
    public function testLoggerMockType() {
        $mockLogger = $this->createMock(LoggerInterface::class);

        $this->assertTrue(is_a($mockLogger, LoggerInterface::class));
        $this->assertFalse(is_a($mockLogger, FileLogger::class));
    }
}

In this example, we verify that the mock object implements the specified interface. Even if it is a mock object, is_a() can still correctly determine whether its type matches the target interface.

Why use is_a() instead of instanceof ?

There is another similar operator instanceof in PHP, which can also be used for type judgment. The difference between the two is:

  • is_a() is functional and can be used more flexibly in some dynamic contexts, such as:

 $className = 'm66.net\\SomeClass';
if (is_a($object, $className)) {
    // Execute specific logic
}
  • instanceof is more suitable for use in static contexts, but is_a() is more convenient when the class name is a dynamic string.

In some mock scenarios, if you take out a mock service from a container and need to dynamically determine whether it meets a certain type, using is_a() will appear more concise:

 $service = $container->get('logger_mock'); // From m66.net Service Container
if (is_a($service, LoggerInterface::class)) {
    $service->log('This is a log');
}

Things to note

  1. If you pass in a class name string instead of an object, make sure to set the third parameter $allow_string to true , otherwise false will be returned.

  2. is_a() determines the type relationship, not the specific implementation details of the class. Therefore, it does not care whether the object is created through mock, and will return true as long as the inheritance/implementation relationship is established.

Summarize

Judging the type of mock object in automated testing is an important step to ensure mock rationality and debugging problems. is_a() provides a flexible, dynamic way to achieve this. It is especially suitable for logical branching in testing based on type, especially in scenarios where service containers, dependency injection, or simulate polymorphic behavior. With is_a() , we can verify the structure and behavior of mock with more confidence, thereby improving the accuracy and maintainability of the test.