I am trying to mock the LaravelScoutBuilder class in one of my Pest tests with Mockery. The goal is to force the throwing of an exception to test my fallback code:
Controller
try {
return self::search($term)->get();
} catch (Exception $e) {
//Want to test code here is working well
}
The static search method eventually calls the following from within the LaravelScout package:
LaravelScoutBuilder
public static function search($query = '', $callback = null)
{
return app(static::$scoutBuilder ?? Builder::class, [
'model' => new static,
'query' => $query,
'callback' => $callback,
'softDelete' => static::usesSoftDelete() && config('scout.soft_delete', false),
]);
}
Because the Builder::class is resolved using the app helper, I think I can mock it using the following in my tests:
Pest Test
$this->instance(LaravelScoutBuilder::class,
Mockery::mock(LaravelScoutBuilder::class, function (MockInterface $mock) {
$mock
->makePartial()
->shouldReceive('get')
->andThrow(new Exception('Search error'));
})
);
However, the normal Builder class is used by my controller so the exception is never thrown and my code is not tested.
If I dump(app(static::$scoutBuilder ?? Builder::class))
without the constructor arguments then I do get an instance of the mocked class. But as the arguments in the array are passed I get an instance of the original class instead.
What do I need to change in my mock to get the behaviour I want? I have tried both with and without makePartial() with no change.