Best answer here so far is I was doing it wrong. Service Providers run way before a controller is even loaded, and, when unit testing, Laravel's Illuminate\Foundation\Testing\TestCase
loads the application (calling all service providers' both boot
and register
methods) during execution of the setUp
method, way before any calls can be made out during the execution of any individual test.
I tried finding a solution by moving the logic down and got something to work, something along the lines of:
class MyTestClass extends TestCase
{
public function setUp()
{
// No call to parent::setUp()
// From: Illuminate\Foundation\Testing\TestCase
$this->app = $this->createApplication();
$this->client = $this->createClient();
// Not this one!
//$this->app->setRequestForConsoleEnvironment();
$this->app->boot();
// ...
}
public function testWhatever()
{
// Calls to this will now actually have a request object
$this->call('GET', '/api/v1/courses');
}
}
But that just can't be right, at least it doesn't feel so.
Instead, I figure it's probably best not to rely on anything in the Request
object from within Service Providers. Instead, why not just inject an object that can do what I need it to do in the controller I want it to? No Service Provider necessary, and I can easily mock any object other than Request
in Unit Tests. I should've believed the docs.
Update
Taking this answer to my own question a bit further, I believe my original mistake was that I was utilizing the Request
object within a Service Provider. I think, on retrospection, that you should probably never use the Request
object at all within a service provider, because providers get loaded for everything related to laravel (including artisan commands, which of course should have no request). My original code worked in the browser, but I probably would have noticed issues had I tried to run any artisan commands.