If you’re doing much testing in Laravel, you may have found yourself writing a lot of code like this for mock objects:
$mockService = Mockery::mock(PaymentService::class); $mockService->shouldReceive('voidPayment')->andThrow(new PaymentException("Couldn't void payment")); app()->instance(PaymentService::class, $mockService);
Sometimes you’ll find yourself duplicating versions of this code throughout a class if you’re testing a lot of interactions with an outside service. It’s not a big deal, but it’s a little tedious. (Also, I tend to forget the last line and not understand why we’re hitting the real service instead of the mock.)
I’ve made myself a little shortcut:
// TestCase.php protected function bindMock(string $className, callable $configuration) { $mock = Mockery::mock($className); call_user_func($configuration, $mock); app()->instance($className, $mock); }
Once that code is in my base TestCase class, I can use the following code in my test cases:
$this->bindMock(PaymentService::class, function ($mock) { $mock->shouldReceive('voidPayment')->andThrow(new PaymentException("Couldn't void payment")); });
It’s not a huge simplification, but I do think it’s a little easier to read and easier to not screw up.
Be First to Comment