Testing traits that declare a constructor with dependencies

Traits are a mechanism for reusing code in language with inheritance such as PHP. A trait attempts to reduce some limitations of simple inheritance by allowing the developer to reuse a number of methods in independent classes. They also reduce the complexity and problems associated with multiple inheritance.

I have already been confronted with a unit test of a trait declaring a constructor with dependencies. The solutions a had implemented did not work because there was a bug in PHPUnit 6.5.14 that I was using. Then I created a bug in PHPUnit (see link https://github.com/sebastianbergmann/phpunit/issues/3722). Thanks to Sebastian Bergmann for fixing the bug. The solution will be available in PHPUnit 8.2.3

Class to test

Here is an example of trait to test:

<?php

namespace AppBundle\Traits;

use AppBundle\Service\myClass;

/**
 * trait MyTrait
 */
trait MyTrait
{
    /**
     * @var MyClass
     */
    private $myClass;

    /**
     * MyTrait constructor.
     *
     * @param MyClass $myClass
     */
    public function __construct(MyClass $myClass)
    {
        $this->myClass = $myClass;
    }

    /**
     * @return string
     */
    public function method(): string
    {
        return $this->myClass->myMethod();
    }
}

The dependency class:

<?php

namespace AppBundle\Service;

/**
 * Class MyClass
 */
class MyClass
{
    /**
     * @return string
     */
    public function myMethod(): string
    {
        return 'Hello word !';
    }
}

Unit test

The unit test is:

<?php

namespace Tests\AppBundle\Traits;

use AppBundle\Traits\MyTrait;
use AppBundle\Service\MyClass;
use PHPUnit\Framework\TestCase;

class TestMyTraitTest extends TestCase
{
    /**
     * Test method
     */
    public function testMethod()
    {
        $myClass = $this->createMock(MyClass::class);
        $myClass->expects($this->once())
            ->method('myMethod')
            ->willReturn('some-string');

        $myTrait = $this->getObjectForTrait(MyTrait::class, [$myClass]);

        $this->assertSame('some-string', $myTrait->method());
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *