I have a trait:
trait A {
function foo() {
...
}
}
and a class that uses the trait like this:
class B {
use A {
foo as traitFoo;
}
function foo() {
$intermediate = $this->traitFoo();
...
}
}
I want to test the class' foo() method and want to mock (with Mockery) the behavior of the trait's foo() method. I tried using a partial and mocking traitFoo() like:
$mock = Mockery::mock(new B());
$mock->shouldReceive('traitFoo')->andReturn($intermediate);
But it doesn't work.
Is it possible to do this? Is there an alternative way? I want to test B::foo() isolating it from the trait's foo() implementation.
Thanks in advance.
The proxy mock you are using proxies calls from outside the mock, so internal calls within the class $this->... cannot be mocked.
If you have no final methods, you still can use normal partial mock or a passive partial mock, which extends the mocked class, and don't have such limitations:
$mock = Mockery::mock(B::class)->makePartial();
$mock->shouldReceive('traitFoo')->andReturn($intermediate);
$mock->foo();
UPDATE:
The full example with non-mocked trait functions:
use Mockery as m;
trait A
{
function foo()
{
return 'a';
}
function bar()
{
return 'd';
}
}
class B
{
use A {
foo as traitFoo;
bar as traitBar;
}
function foo()
{
$intermediate = $this->traitFoo();
return "b$intermediate" . $this->traitBar();
}
}
class BTest extends \PHPUnit_Framework_TestCase
{
public function testMe()
{
$mock = m::mock(B::class)->makePartial();
$mock->shouldReceive('traitFoo')->andReturn('c');
$this->assertEquals('bcd', $mock->foo());
}
}