Skip to content

Testing

Faking the manager

Compose::fake() swaps the manager for one that records redeploys instead of running them. An enabled stack records Redeployed, a disabled one Skipped, and no env file is written and no docker command runs. It also calls Process::fake(), so a stack's status(), logs(), or exec() never reach a daemon either. When a test needs specific process results as well, call Process::fake([...]) before Compose::fake(): an existing fake is kept, but a bare one installed first would shadow patterns you add afterwards.

use Mozex\Compose\Facades\Compose;

it('redeploys the search stack after a deploy', function (): void {
    $fake = Compose::fake();

    $this->artisan('deploy:after')->assertSuccessful();

    $fake->assertRedeployed('meilisearch')
        ->assertSkipped('mailpit');
});

Assertions: assertRedeployed($name), assertSkipped($name), assertNotRedeployed($name), assertNothingRedeployed(). results() returns the recorded RedeployResult per stack. shouldFail($name) makes the next redeploy of that stack report Failed, for testing the code that reacts to one.

Faking the processes only

When you want the real recipe to run against a fake daemon, use Process::fake() directly. Every docker invocation goes through Laravel's Process facade with an array command, so assertRan sees the exact arguments:

use Illuminate\Process\PendingProcess;
use Illuminate\Support\Facades\Process;

Process::fake();

Compose::redeploy('meilisearch');

Process::assertRan(fn (PendingProcess $process): bool => in_array('up', $process->command, true)
    && in_array('--wait', $process->command, true));

One thing to know about fake patterns: Symfony quotes every argument on Linux, so a pattern like '*ps --format*' matches on Windows and not on CI. Put * between tokens ('*ps*--format*') or match on $process->command in a closure.

Testing a stack class

A stack class is plain PHP. Test its environment() and enabled() against config the way you'd test anything that reads config:

it('derives the port from the scout host', function (): void {
    config()->set('scout.meilisearch.host', 'http://127.0.0.1:7701');

    expect((new MeilisearchStack)->environment()['MEILISEARCH_PORT'])->toBe(7701);
});

And keep the stacks consistent with their compose files with the doctor report in an architecture test.

Scroll to top