Decided to rewrite my controller and use the Service Container so that I mock the object and replace it when testing. In my service container:
$this->app->when(MyController::class)
->needs('$test_model')
->give(function() {
if($test_model_id = request()->get('test_model_id')) {
return TestModel::where('id', $test_model_id)->first();
}
});
Then rejig the controller to accept TestModel as an argument which will be injected by the Service Container:
class MyController extends Controller
{
public function __invoke(TestModel $test_model)
{
if($test_model) {
$test_model = TestModel::where('id', $test_model_id)->first();
$test_model->do_something();
...
} else {
abort(404);
}
}
My test can just do the follwing:
$this->instance(TestModel::class, $this->partialMock(TestModel::class, function (\Mockery\MockInterface $mock) {
$mock->shouldReceive('do_something')->once();
}));
$this->get('/my_route?test_order_id='.$model->id)->assertSuccessful();
This now passes.
One thing to bear in mind is that, it doesn't matter what my get params are for the test - the mock ensures that a mocked object will always be passed to the controller. So I'll probably go onto to write a test passing null to test failure and another to ensure my binding in the Service Container is correct.