Vinícius Ferraz
Vinícius Ferraz

Reputation: 153

How to inspect the actual Laravel Command output while writing tests?

I was writing a very basic test for a Laravel Artisan Console Command, like this:

$this->artisan("my-command", ["--some-option" => "some-value"])
     ->expectsOutput("the expected output");

The test didn't pass. I got really troubled because "the expected output" was exactly what the command was outputting when executed mannualy.

But that's ok, I just have to inspect what the command output actually is when executed through automated tests, right? But wait, how do I do that?

I tried the following:

$output = new BufferedConsoleOutput();
Artisan::call("my-command", ["--some-option", "some-value"], $output);
// dd($output->fetch()
$this->assertTrue($output->fetch() === "the expected output");

But $output->fetch() seems to be always empty.

In brief: How do I print the actual output of a Laravel command in the context of a test?

Upvotes: 11

Views: 6052

Answers (1)

miken32
miken32

Reputation: 42712

If you prevent Laravel from mocking the console output, you can capture it for inspection.

Assuming you have this test that fails:

public function testStuffDoesntBreak(): void
{
    $this->artisan("my-command", ["--some-option" => "some-value"])
        ->expectsOutput("the expected output");
}

You can rewrite it to this:

use Illuminate\Support\Facades\Artisan;
...

public function testStuffDoesntBreak(): void
{
    $this->withoutMockingConsoleOutput()
        ->artisan("my-command", ["--some-option" => "some-value"]);
    // capture the text output from the command
    $result = Artisan::output();
    // use standard text assertions
    $this->assertEquals("the expected output", $result);
}

When you've disabled console mocking, the artisan() method stops being fluent and instead returns the exit code of the command. But it does allow the Artisan facade to access its output.


Whether you want to rewrite your tests to always mock the output, or just change them on the fly when trying to debug an error, is down to personal preferences. I've done the latter, as I'd rather not miss out on fluent methods like expectsTable().

Upvotes: 27

Related Questions