mardi 17 août 2021

Unit testing individual pieces of Laravel artisan commands without running the entire command

I have some pretty complicated commands with a lot of moving parts. I want to write tests for individual parts of those commands. This is proving to be a real pain the way I am currently doing it because the input and output interfaces are not instantiated until the run() method is hit during a typical programmatic call.

e.g.

Artisan::call('do:something', ['foo' => 'whatever', '--bar' => true]);

As such, I've written most of my tests like so:

protected function setUp()
{
    parent::setUp();

    $this->command = new DoSomething;
    $this->thing = Something::first();
}

/** @test */
public function it_succeeds_and_fails_at_doing_something()
{
    // Test happy path.
    $success = $this->command->verySuccess($this->thing->id);

    $this->assertInstanceOf(SomethingSuccessful::class, $success);

    // Test unhappy path.
    $failed = $this->command->verySuccess('nope');

    $this->assertNull($failed);
}

The problem with the above is that within the command's code is scattered calls such as if ($this->option('bar')) { ... } which always fails with Call to a member function getOption() on null

Aside from the exception, it also makes it problematic to test these specific methods with the right options and arguments set.

How do I get around this input issue? Feels like I am going about testing this the wrong way.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire