Testing Laravel (5.1) console commands with phpuni

2019-01-26 18:57发布

问题:

What is the best way to test Laravel console commands?

Here is an example of a command I'm running. It takes in a value in the constructor and in the handle method.

class DoSomething extends Command
{
    protected $signature = 'app:do-something';
    protected $description = 'Does something';

    public function __construct(A $a)
    {
        ...
    }

    public function handle(B $b)
    {
        ...    
    }
}

In my test class, I can mock both A and B, but I can't figure out how to pass $a in.

$this->artisan('app:do-something', [$b]);

Is it possible? Or am I going about this all wrong? Should I pass everything in thought the handle() method?

Thanks.

回答1:

You will have to change around how you call the command in testing, but it is possible to mock an object passed through.

If the class used by Artisan is dependency-injected like this:

public function __construct(ActualObject $mocked_A)
{
    //
}

Then write up the test case like this:

$mocked_A = Mockery::mock('ActualObject');
$this->app->instance('ActualObject', $mocked_A);

$kernel = $this->app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
    $input = new Symfony\Component\Console\Input\ArrayInput([
        'command' => 'app:do-something',
    ]),
    $output = new Symfony\Component\Console\Output\BufferedOutput
);
$console_output = $output->fetch();

The $this->app->instance('ActualObject', $mocked_A); line is where you are able to call upon and use the mocked version of your class, or object, instead of the actual.

This will work in Laravel or Lumen.