Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing code that uses get_class with PHPUnit mock objects

Tags:

php

phpunit

Using PHPUnit and a mock object, I am trying to test some code that uses get_class to determine if an object is included by a filter or not.

Here is the class to be tested:

class BlockFilter implements FilterInterface
{
    private $classes;

    public function __construct(array $classes = array())
    {
        $this->classes = $classes;
    }

    public function isIncluded(NodeTraversableInterface $node)
    {
        if (Type::BLOCK != $node->getDocumentType()) {
            return false;
        }

        if (! empty($this->classes)) {
            /*** HERE IS THE PROBLEM: ***/
            return in_array(get_class($node), $this->classes);
        }

        return true;
    }
}

Here is the method from my unit test:

public function testIfContainerBlockIsIncluded()
{
    $containerBlock = $this->getMock('Pwn\ContentBundle\Document\ContainerBlock');
    $containerBlock->expects($this->any())->method('getDocumentType')->will($this->returnValue(Type::BLOCK));

    $filter = new BlockFilter(array('Pwn\ContentBundle\Document\ContainerBlock'));
    $this->assertTrue($filter->isIncluded($containerBlock));
}

The mock object $containerBlock behaves like the real object Pwn\ContentBundle\Document\ContainerBlock; even code using instanceof works (because PHPUnit makes it a subclass of the real class, I believe).

The code being tested uses get_class to get a string value of the class and compare it with an array of expected class names. Unfortunately, for the mock object, get_class returns something like this:

Mock_ContainerBlock_ac231064

(the _ac231064 suffix changes on each invocation).

This causes my test to fail, so what are my options?

  • Rework the code to avoid using get_class? This implies get_class should not be used when trying to write testable code.
  • Use a real instance of the ContainerBlock class instead of a mock? This means we are effectively testing both classes at once.
  • Some other awesomely clever trick that you're all going to suggest??? ;)

Thanks for any help...

like image 519
fazy Avatar asked Jan 04 '13 12:01

fazy


People also ask

Which method is used to create a mock with PHPUnit?

PHPUnit provides methods that are used to automatically create objects that will replace the original object in our test. createMock($type) and getMockBuilder($type) methods are used to create mock object. The createMock method immediately returns a mock object of the specified type.

What are mock objects in testing?

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways, most often as part of a software testing initiative.

What is stub in PHPUnit?

Stubs are used with query like methods - methods that return things, but it's not important if they're actually called. $stub = $this->createMock(SomeClass::class); $stub->method('getSomething') ->willReturn('foo'); $sut->action($stub);


1 Answers

Pass the Mock's class name in the test:

new BlockFilter(array(get_class($this->containerBlock)));
like image 125
Gordon Avatar answered Oct 06 '22 01:10

Gordon