> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Externe processen uitvoeren in packages en Process::fake

> Legt met de Process-facade van Laravel 13 de argumenten van externe commando's, timeouts, foutexceptions, fakes in tests en het matchen van array-commando's uit.

Wanneer een package externe commando's zoals `ffmpeg` of `git` aanroept, worden verschillen in de omgeving van de gebruikende applicatie en mislukkingen direct het gedrag van het package. Roep `shell_exec()` of `exec()` niet rechtstreeks aan, maar voer commando's uit via de **Process-facade** en vervang ze in tests door `Process::fake()`.

> [!NOTE]
>
> Deze pagina is gericht op Laravel 13 en controleert de implementatie van Framework `v13.42.0`. Ze gaat uit van kennis van [processen](https://kawax.biz/nl/processes.md) en [packages testen](https://kawax.biz/nl/advanced/package-testing.md). Het matchen van array-commando's op deze pagina gaat uit van de manier waarop Symfony Process, dat Process intern gebruikt, argumenten omzet.

## Waarom je directe uitvoering vermijdt

Directe functieaanroepen kun je in tests niet vervangen, en elke aanroeper gaat anders om met timeouts en exitcodes. Via de Process-facade maak je het vastleggen van uitvoeringen, fakes, timeouts en exceptions bij mislukking uniform.

```mermaid theme={null}
flowchart LR
    A["Wrapperklasse<br>van het package"] --> B["Process facade<br>PendingProcess"]
    B --> C{"Fake<br>geregistreerd?"}
    C -->|Ja| D["FakeProcessResult<br>er start geen extern commando"]
    C -->|Nee| E["Extern commando starten"]
    E --> F["ProcessResult"]
    D --> F
    F --> G["throw() maakt van mislukkingen exceptions"]
```

## Geef commando's door als array

Een commando als string wordt door `sh` geïnterpreteerd. Bevat het gebruikersinvoer, dan ontstaan problemen met aanhalingstekens en ruimte voor injectie. Geef binnen een package argumenten door als array.

```php theme={null}
<?php

namespace Vendor\Package\Support;

use Illuminate\Support\Facades\Process;

final class VideoConverter
{
    public function toMp4(string $source, string $target): void
    {
        Process::timeout(120)
            ->run(['ffmpeg', '-y', '-i', $source, $target])
            ->throw();
    }
}
```

De standaardtimeout van `PendingProcess` is `60` seconden en de idle-timeout is `null`. Stel voor lange conversies `timeout()` expliciet in, en combineer het met `idleTimeout()` voor verwerking waarvan de uitvoer kan stilvallen.

## Exceptions en meldingen bij mislukking

`ProcessResult::throw()` gooit een `ProcessFailedException` wanneer de exitcode geen succes aangeeft. De melding bevat het uitgevoerde commando, de exitcode en de standaarduitvoer en standaardfoutuitvoer.

> [!WARNING]
>
> Als je geheimen in commando-argumenten zet, komen ze in de melding van `ProcessFailedException` terecht en kunnen ze in logs of op het scherm verschijnen. Geef tokens niet als argument door. Geef ze mee met `env()` of schrijf ze in het configuratiebestand van het commando.

Timeouts worden weergegeven door `ProcessTimedOutException` en idle-timeouts door `ProcessIdleTimedOutException`. Documenteer voor de gebruikers van je package welke exceptions je gooit en wat ze kunnen verwachten wanneer ze die afvangen.

## Fake in tests

Vervang externe commando's in tests door `Process::fake()`. Met `Process::result()` geef je de standaarduitvoer, de standaardfoutuitvoer en de exitcode op.

```php theme={null}
<?php

namespace Vendor\Package\Tests\Feature;

use Illuminate\Contracts\Process\ProcessResult;
use Illuminate\Process\Exceptions\ProcessFailedException;
use Illuminate\Process\PendingProcess;
use Illuminate\Support\Facades\Process;
use Vendor\Package\Support\VideoConverter;
use Vendor\Package\Tests\TestCase;

class VideoConverterTest extends TestCase
{
    public function test_it_runs_ffmpeg_with_the_expected_arguments(): void
    {
        Process::fake([
            '*' => Process::result(output: 'converted'),
        ]);

        (new VideoConverter)->toMp4('/tmp/in.mov', '/tmp/out.mp4');

        Process::assertRan(
            fn (PendingProcess $process, ProcessResult $result) => $process->command === ['ffmpeg', '-y', '-i', '/tmp/in.mov', '/tmp/out.mp4']
        );
    }

    public function test_it_fails_when_ffmpeg_exits_with_an_error(): void
    {
        Process::fake([
            '*' => Process::result(errorOutput: 'Invalid data', exitCode: 1),
        ]);

        $this->expectException(ProcessFailedException::class);

        (new VideoConverter)->toMp4('/tmp/in.mov', '/tmp/out.mp4');
    }
}
```

Als je een closure aan `assertRan()` doorgeeft, kun je `command`, `timeout`, `environment` en andere eigenschappen van `PendingProcess` controleren. Array-commando's worden met `$process->command` op exacte gelijkheid vergeleken, zodat tests wijzigingen in de volgorde of waarden van argumenten opmerken.

## Fake-sleutels voor array-commando's

Intern vergelijkt Process de sleutels van `fake()` met `Str::is()` met het resultaat van `getCommandline()`. Array-commando's worden omgezet in een string met aanhalingstekens voor de shell, dus een stringpatroon zoals `'ffmpeg*'` matcht niet. Gebruik in tests van array-commando's een van de volgende manieren.

| Aanpak | Wanneer gebruiken | Let op |
| - | - | - |
| De sleutel `'*'` | Ongeacht het commando hetzelfde resultaat teruggeven | Je merkt moeilijk op dat een ander commando wordt aangeroepen |
| `Process::assertRan()` | Argumenten na de aanroep controleren | Bereid het fake-antwoord apart voor |
| Fake met closure | Het resultaat laten afhangen van de argumenten | De logica wordt complex, dus houd het doel van de test smal |

## Onverwachte externe commando's voorkomen

Gebruik `preventStrayProcesses()` om externe commando's te detecteren die in tests niet zouden moeten draaien. Commando's die met geen enkele fake overeenkomen, leiden tot een `RuntimeException` en starten niet echt.

```php theme={null}
protected function setUp(): void
{
    parent::setUp();

    Process::preventStrayProcesses();
}
```

## Als je een geïnjecteerde Factory gebruikt

Als de constructor van je package `Illuminate\Process\Factory` ontvangt, controleer dan of de toestand van `Process::fake()` de geïnjecteerde instantie bereikt. De facade cachet de opgeloste instantie en `swap()` vervangt de instantie in de container. Of `Factory` in de container gedeeld wordt, kun je echter niet overlaten aan een expliciete registratie door het framework. Controleer het daarom in een test.

Bereikt de fake de geïnjecteerde instantie niet, vervang de Factory dan expliciet in de test of ontwerp het package zo dat het via de `Process`-facade loopt. Controleer in beide gevallen met `assertRan()` dat de aanroep is vastgelegd. Zo merk je een vergeten vervanging op.

## Extra controles voor onderhoud op lange termijn

| Controle | Doel |
| - | - |
| Test die de volgorde van array-argumenten vastlegt | Opmerken wanneer de positie van `-y` of van invoer en uitvoer verandert |
| Exception en melding bij mislukking controleren | De foutafhandeling van gebruikers ongewijzigd houden |
| Standaardwaarden van `timeout()` en `idleTimeout()` controleren | Een wijziging van standaardwaarden behandelen als gedragswijziging voor gebruikers |
| `preventStrayProcesses()` inschakelen | Onverwacht starten van externe commando's in tests stoppen |
| Controleren dat er geen geheimen als argument worden doorgegeven | Lekken in exceptionmeldingen en logs voorkomen |

## Geraadpleegde primaire bronnen

* [Officiële Laravel-documentatie: processen](https://github.com/laravel/docs/blob/13.x/processes.md)
* [Officiële Laravel-documentatie: Process::fake en assertRan](https://github.com/laravel/docs/blob/13.x/processes.md#faking-processes)
* [Process Factory: fake en assertRan](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Process/Factory.php)
* [PendingProcess: standaardtimeouts en matchen van fakes](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Process/PendingProcess.php)
* [ProcessResult: gedrag van throw()](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Process/ProcessResult.php)
* [ProcessFailedException: opbouw van de melding](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Process/Exceptions/ProcessFailedException.php)
* [Facade: caching en swap()](https://github.com/laravel/framework/blob/v13.42.0/src/Illuminate/Support/Facades/Facade.php)


## Related topics

- [Geavanceerde onderwerpen](https://kawax.biz/nl/advanced/index.md)
- [Processen](https://kawax.biz/nl/processes.md)
- [HTTP-clients en tests voor packages](https://kawax.biz/nl/advanced/package-http-client.md)
- [Views van packages overschrijven en bijwerken](https://kawax.biz/nl/advanced/package-views.md)
- [Queue-jobs in packages en compatibiliteit bij updates](https://kawax.biz/nl/advanced/package-queue-jobs.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.