Mockery - creating mock with constructor data

Viewed 168

I'm trying to use Laravel's app service container to resolve out mocked instances for testing. I've created a mock which works when making an instance of CS_REST_Subscribers alone, however if I provide arguments to the service container my mock no longer applies.

$this->mock(\CS_REST_Subscribers::class, function (MockInterface $mockery) {
    $mockery
        ->shouldReceive('add')
        ->once();
});
get_class(app()->make(\CS_REST_Subscribers::class)); // returns Mockery_2_CS_REST_Subscribers

get_class(app()->make(\CS_REST_Subscribers::class, [
    'list_id' => 'testing',
    'auth_details' => ['api_token' => '123']
])); // returns CS_REST_Subscribers

Dump 1 gives me Mockery_2_CS_REST_Subscribers but dump 2 gives me CS_REST_Subscribers.

Any idea how to apply the mock even when passed constructor arguments? I can't help but feel like I'm missing something here...

1 Answers

I've just found the solution off the back of a Laravel raised issue https://github.com/laravel/framework/issues/19450#issuecomment-451549582

It seems that when passing parameters, Laravel's built in mocking bypasses building a mock instance.

The solution was to create my Mockery mock and then bind it to the service container directly, thus forcing Laravel to resolve what it has been given in the service container.

$mock = \Mockery::mock(\CS_REST_Subscribers::class)->makePartial();
$mock->shouldReceive('add')->once();
$this->app->bind(\CS_REST_Subscribers::class, fn() => $mock);
Related