Search code examples
phpunit-testingtestingmockery

Mockery test trait and mock method


I try to unit-test a trait with two methods. I want to assert the result of foo which calls another method inside the trait:

<?php
trait Foo {
    public function foo() {
        return $this->anotherFoo();
    }

    public function anotherFoo() {
        return 'my value';
    }
}

/** @var MockInterface|Foo */
$mock = Mockery::mock(Foo::class);
$mock
    ->makePartial()
    ->shouldReceive('anotherFoo')
    ->once()
    ->andReturns('another value');

$this->assertEquals('another value', $mock->foo());

I get the following result when I run phpunit:

There was 1 failure:

1) XXX::testFoo
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'another value'
+'my value'

Is this generally possible like this?


Solution

  • I don't think you can directly mock a trait like that. What does seem to work is to do the same thing but using a class that uses the trait. So, for example, create a test Bar class that uses Foo and then make a partial mock of that. That way you're working with a real class and Mockery seems happy to override the trait method.

    trait Foo {
        public function foo() {
            return $this->anotherFoo();
        }
    
        public function anotherFoo() {
            return 'my value';
        }
    }
    
    class Bar {
        use Foo;
    }
    
    /** @var MockInterface|Bar */
    $mock = Mockery::mock(Bar::class);
    $mock
        ->makePartial()
        ->shouldReceive('anotherFoo')
        ->once()
        ->andReturns('another value');
    
    $this->assertEquals('another value', $mock->foo());