Summer Sale! All accounts are 50% off this week.

Olsza's avatar
Level 11

Tests i.e. what parameters were used with "Artisan::call()"?

Hello all, I have made 'artisan' commands that have different parameters/options. Since some of the commands are to be run by people who do not have access to a terminal, so I created a "form" where the user can select the available parameters and enter their values. The form itself is validated, but I want to add tests to the form so that selecting a parameter and entering its value it runs "Artisan::call()*" with specific parameters, how to make such a test? I'll add that the commands themselves have tests written in PEST PHP, now it's time to make the tests of the form made on LiveWire have tests and that it runs the given command with the appropriate parameters.

For example Let's assume that a given form executes the Artisan command "app:company" and that this command takes the parameters --tin=456987 [email protected] --delete-address=false. It example, but that we assume that the parameter --tin is required if at least one other parameter is present, etc. The point is that the command can be urchuchamiany with different parameters, and whether the given is good or bad is responsible tests from the command. He wants to create tests in PEST for Livewire, he checked that after the backend runs "app:company" well with the parameters correctly, that for example it would be "Artisan::call(app:company --tin=456987 [email protected])" and not "Artisan::call(app:company --tin=456987 [email protected] --delete-address=false)" or "Artisan::call(app:company --tin=456987)".

Any suggestions?

0 likes
3 replies
LaryAI's avatar
Level 58

One solution could be to create a test that mocks the Artisan facade and checks that the correct parameters are passed to it based on the form input. Here's an example:

use Illuminate\Support\Facades\Artisan;
use Livewire\Livewire;
use Tests\TestCase;

class CompanyFormTest extends TestCase
{
    /** @test */
    public function it_calls_the_app_company_command_with_correct_parameters()
    {
        // Mock the Artisan facade
        Artisan::shouldReceive('call')->once()->with('app:company', [
            '--tin' => '456987',
            '--new-mail' => '[email protected]',
            '--delete-address' => 'false',
        ]);

        // Submit the Livewire form with the correct parameters
        Livewire::test(CompanyForm::class)
            ->set('tin', '456987')
            ->set('newMail', '[email protected]')
            ->set('deleteAddress', 'false')
            ->call('submit');

        // Assert that the Artisan facade was called with the correct parameters
        Artisan::assertSent(function ($command) {
            return $command->getName() === 'app:company' &&
                $command->hasOption('tin') &&
                $command->option('tin') === '456987' &&
                $command->hasOption('new-mail') &&
                $command->option('new-mail') === '[email protected]' &&
                $command->hasOption('delete-address') &&
                $command->option('delete-address') === 'false';
        });
    }
}

This test uses the shouldReceive method from Mockery to mock the Artisan::call method and ensure that it is called once with the correct parameters. It then uses the Livewire::test method to submit the Livewire form with the correct parameters and calls the submit method on the component. Finally, it uses the assertSent method from the Artisan facade to assert that the app:company command was called with the correct parameters.

Olsza's avatar
Level 11

@LaryAI Almost everything ok, but the error is that Artisan::assertSent() does not exist, i.e. the assertSent() facade does not exist in "Artisan" i.e. in "Illuminate\Support\Facades\Artisan;".

 calls the app:company command with correct parameters
   Mockery\Exception\BadMethodCallException 

  Method Mockery_2_App_Console_Kernel::assertSent() does not exist on this mock object

  at vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:338
    334▕         if (! $instance) {
    335▕             throw new RuntimeException('A facade root has not been set.');
    336▕         }
    337▕ 
  ➜ 338▕         return $instance->$method(...$args);
    339▕     }
    340▕ }
Olsza's avatar
Level 11

@LaryAI By removing after the following code ie. Artisan::assertSent(....


        // Assert that the Artisan facade was called with the correct parameters
        Artisan::assertSent(function ($command) {
            return $command->getName() === 'app:company' &&
                $command->hasOption('tin') &&
                $command->option('tin') === '456987' &&
                $command->hasOption('new-mail') &&
                $command->option('new-mail') === '[email protected]' &&
                $command->hasOption('delete-address') &&
                $command->option('delete-address') === 'false';
        });

and an error appears:

calls the app:company command with correct parameters
   Mockery\Exception\BadMethodCallException 

  Received Mockery_2_App_Console_Kernel::output(), but no expectations were specified

  at vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:338
    334▕         if (! $instance) {
    335▕             throw new RuntimeException('A facade root has not been set.');
    336▕         }
    337▕ 
  ➜ 338▕         return $instance->$method(...$args);
    339▕     }
    340▕ }
    341▕ 

Please or to participate in this conversation.