Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

instance mock and normal mock different behaviour while calling another method inside class #1186

Open
sakarikl opened this issue Jun 14, 2022 · 1 comment

Comments

@sakarikl
Copy link
Contributor

class Test
{
    public function test() : string
    {
        return 'own';
    }

    public function test2() : string
    {
        return $this->test();
    }
}

$object = new Test();


$mock = \Mockery::instanceMock($object)
    ->makePartial();

$mock->shouldReceive('test')->andReturn('mock');

var_dump($mock->test());
var_dump($mock->test2());

$mock2 = \Mockery::mock(Test::class)
    ->makePartial();

$mock2->shouldReceive('test')->andReturn('mock');

var_dump($mock2->test());
var_dump($mock2->test2());

results in

string(4) "mock"
string(3) "own"
string(4) "mock"
string(4) "mock"

Instance mock does not mock test method which is called from test2 method. I did not find any documentation stating this behaviour.

@ghostwriter
Copy link
Member

Hey @sakarikl

I believe the behavior you are describing is Proxied Partial Mock.

$object = new Test();

$mock1 = \Mockery::instanceMock($object)->makePartial();

// ^ $mock1 is the same as $mock2 ⌄

$mock2 = \Mockery::mock($object)->makePartial();

It intercepts calls and reroutes them to the proxied object (which we construct and pass in) for methods which are not subject to any expectations. Indirectly, this allows us to mock methods marked final since the Proxy is not subject to those limitations. The tradeoff should be obvious - a proxied partial will fail any typehint checks for the class being mocked since it cannot extend that class.

In the example code you provided, the test2() method does not have any expectations, so mockery intercepts that call and reroutes it to the proxied object (returning "own").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants