MarcoLe
MarcoLe

Reputation: 2509

PhpUnit - Mocked method is not called

So I have a method which I want to component test and I can not mock a used method of the injected class:

Method to test

class PageEventHandler
{
    public const PAGE_TYPE_PRODUCT_LIST = 'product_list';
    ...
    private $pagePublishValidator;

    public function __construct(
        ...
        PagePublishValidator $pagePublishValidator
    ) {
        ...
        $this->pagePublishValidator = $pagePublishValidator;
    }

    public function preUpdate(AbstractObject $object)
    {
        $this->pagePublishValidator->validate($object);
    }
}

In the publishValidator class I have a method which I want to mock getPrevious, which is method of a trait GetPrevious.php. The publishValidator class looks like:

Validate method of injected class

    public function validate(Page $object)
    {
        /** @var Page $previous */
        $previous = $this->getPrevious($object);

        var_dump('-----------------'); // <-- goes into here
        if (!$previous) {
            // a newly created object has no children
            return;
        }

        var_dump('+++++++++++++++++++'); // <-- Does not go into here
        var_dump('should go into here');
    }

test case

public function testPreUpdateWithChildPageAndNewParent()
{
    $rootPage = $this->buildPage('', 'root');

    $trait = $this->getMockBuilder(GetPrevious::class)
        ->setMethods(['getPrevious'])
        ->disableOriginalConstructor()
        ->getMockForTrait();

    $trait->expects($this->once())
        ->method('getPrevious')
        ->with($rootPage)
        ->willReturn($rootPage); //Method called 0 times instead of one time, so mock seems to be wrong

    $handler = new PageEventHandler(
        $this->createAssertingMockProducer([], 0),
        new NullProducer(),
        new PagePublishValidator([PageEventHandler::PAGE_TYPE_PRODUCT_LIST])
    );

    $handler->preUpdate($rootPage);
}

Upvotes: 0

Views: 703

Answers (1)

Philip Weinke
Philip Weinke

Reputation: 1844

The purpose of getMockForTrait is to test a trait standalone (see docs). You have to mock the method on PagePublishValidator:

public function testPreUpdateWithChildPageAndNewParent()
{
    $rootPage = $this->buildPage('', 'root');

    $validator = $this->getMockBuilder(PagePublishValidator::class)
        ->setMethods(['getPrevious'])
        ->setConstructorArgs([PageEventHandler::PAGE_TYPE_PRODUCT_LIST])
        ->getMock();

    $validator->expects($this->once())
        ->method('getPrevious')
        ->with($rootPage)
        ->willReturn($rootPage);

    $handler = new PageEventHandler(
        $this->createAssertingMockProducer([], 0),
        new NullProducer(),
        $validator
    );

    $handler->preUpdate($rootPage);
}

Upvotes: 1

Related Questions