'Method expectsOuput not found on int when testing console commands in Lumen 5.8

According to the Laravel documentation it looks like I should be able to chain methods to artisan commands in a unit test, like:

$this->artisan('make:docs')->expectsOutput('./openapi.yaml was generated.');

But in Lumen, $this->artisan returns an int so that doesn't work. This is the code from Lumen's Testing\TestCase.php:

 /**
 * Call artisan command and return code.
 *
 * @param string  $command
 * @param array   $parameters
 * @return int
 */
public function artisan($command, $parameters = [])
{
    return $this->code = $this->app['Illuminate\Contracts\Console\Kernel']->call($command, $parameters);
}

As a workaround I'm doing this, which isn't ideal since you have to add switches to bypass questions. This is a simple example with output only for questions I pass an array of switches to $this->execute using the $options parameter so I can skip them all and test the final output.

class CommandsTest extends TestCase
{
/**
 * Execute a console command.
 *
 * @param string $className
 * @param string $commandString
 * @param array $options
 *
 * @return CommandTester
 */
private function execute(string $className, string $commandString, array $options = []): CommandTester
{
    $application = new ConsoleApplication();

    $testedCommand = $this->app->make($className);
    $testedCommand->setLaravel(app());
    $application->add($testedCommand);

    $command = $application->find($commandString);

    $commandTester = new CommandTester($command);
    $commandTester->execute(array_merge(['command' => $command->getName()], $options));

    return $commandTester;
}

/**
 * Clean console command output.
 *
 * @param string $output
 *
 * @return string
 */
private function clean(string $output): string
{
    $output = trim($output);

    return str_replace(array("\r\n", "\r"), "\n", $output);
}

/**
 * Test the OpenAPI documentation command.
 *
 * @return void
 */
public function testMakeDocs(): void
{
    $command = $this->execute(DocsMake::class, 'make:docs');

    $output = $this->clean($command->getDisplay());

    $expected = './openapi.yaml was generated.';

    $this->assertSame($expected, $output);
}

Has anyone figured out how to make this work like Laravel so you can chain commands?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source