
# Tests

Queuety fournit une classe `QueueFake` qui remplace la vraie file d’attente par un stockage en mémoire. Les jobs déclenchés sont enregistrés au lieu d’être écrits dans la base de données, et `create_batch()` enregistre également les métadonnées des lots en mémoire. Vous pouvez ainsi vérifier le comportement de déclenchement sans exécuter de workers ni écrire dans la base de données. Le déclenchement par nom de gestionnaire résout toujours celui-ci via le registre ; appelez donc `Queuety::init()` avant de déclencher des jobs avec un gestionnaire sous forme de chaîne. Les instances `Contracts\Job`, `chain()`, `create_batch()` et `batch()` fonctionnent sans cela.

## Configurer la simulation

Appelez `Queuety::fake()` au début de votre test. Cette méthode renvoie une instance `QueueFake` qui enregistre tous les déclenchements ultérieurs.

```php
use Queuety\Queuety;

class SendEmailTest extends \PHPUnit\Framework\TestCase {
    protected function setUp(): void {
        $this->fake = Queuety::fake();
    }

    protected function tearDown(): void {
        Queuety::reset();
    }
}
```

`Queuety::fake()` crée un nouvel objet `QueueFake` et le relie à la façade `Queuety`. `Queuety::dispatch()` et `Dispatchable::dispatch()` enregistrent les jobs ajoutés. `Queuety::chain()` enregistre chaque job enchaîné comme un ajout normal, dans l’ordre de déclenchement. `Queuety::create_batch()` enregistre les jobs ajoutés ainsi que les métadonnées de lot utilisées par `assert_batched()`. `Queuety::batch()` enregistre les jobs ajoutés, mais ne crée pas de fausses métadonnées de lot.

Appelez `Queuety::reset()` dans `tearDown()` pour réinitialiser la simulation entre les tests. Cette méthode efface tout l’état de la façade ; appelez donc à nouveau `Queuety::init()` si un test ultérieur nécessite la vraie file d’attente.

## Vérifier que des jobs ont été ajoutés

### `assert_pushed()`

Vérifiez qu’un job d’une classe donnée a été déclenché au moins une fois.

```php
public function test_welcome_email_is_sent(): void {
    $this->fake = Queuety::fake();

    // Code under test...
    register_new_user( 'user@example.com' );

    $this->fake->assert_pushed( SendWelcomeEmailJob::class );
}
```

Transmettez éventuellement un callback pour filtrer les jobs selon leur charge utile ou d’autres attributs. Le callback reçoit le tableau de données du job enregistré, avec les clés `handler`, `payload`, `queue` et `instance`. `instance` vaut `null` pour les jobs déclenchés via la façade ou le trait `Dispatchable` ; utilisez donc `handler` et `payload` pour les comparer.

```php
$this->fake->assert_pushed( SendWelcomeEmailJob::class, function ( array $job ) {
    return $job['payload']['to'] === 'user@example.com';
} );
```

### `assert_pushed_times()`

Vérifiez qu’un job a été ajouté un nombre exact de fois.

```php
$this->fake->assert_pushed_times( SendEmailJob::class, 3 );
```

### `assert_not_pushed()`

Vérifiez qu’un job n’a jamais été déclenché.

```php
$this->fake->assert_not_pushed( DeleteAccountJob::class );
```

### `assert_nothing_pushed()`

Vérifiez qu’aucun job n’a été déclenché.

```php
public function test_no_jobs_on_invalid_input(): void {
    $this->fake = Queuety::fake();

    process_input( '' ); // invalid, should not dispatch anything

    $this->fake->assert_nothing_pushed();
}
```

## Vérifier les lots

### `assert_batched()`

Vérifiez qu’un lot a été déclenché. Vous pouvez transmettre un callback pour filtrer les lots selon leur contenu.

```php
$this->fake->assert_batched();

$this->fake->assert_batched( function ( array $batch ) {
    return count( $batch['jobs'] ) === 3;
} );
```

Le callback reçoit un tableau contenant les clés `jobs` et `options`.

## Examiner les jobs ajoutés

Utilisez `pushed()` pour récupérer tous les déclenchements enregistrés pour une classe donnée, et `batches()` pour récupérer tous les lots enregistrés.

```php
$emails = $this->fake->pushed( SendEmailJob::class );
// [ ['handler' => '...', 'payload' => [...], 'queue' => 'default', 'instance' => null], ... ]

$batches = $this->fake->batches();
// [ ['jobs' => [...], 'options' => [...]], ... ]
```

## Réinitialiser entre les tests

Appelez `reset()` sur la simulation pour effacer tous les jobs et lots enregistrés sans créer de nouvelle instance.

```php
$this->fake->reset();
```

Vous pouvez aussi appeler `Queuety::reset()` pour démanteler complètement la simulation et effacer tout son état interne.

## Exemple complet

```php
use PHPUnit\Framework\TestCase;
use Queuety\Queuety;

class OrderWorkflowTest extends TestCase {
    private \Queuety\Testing\QueueFake $fake;

    protected function setUp(): void {
        $this->fake = Queuety::fake();
    }

    protected function tearDown(): void {
        Queuety::reset();
    }

    public function test_order_dispatches_payment_job(): void {
        $order = create_order( [ 'total' => 99.99 ] );

        $this->fake->assert_pushed( ProcessPaymentJob::class, function ( array $job ) use ( $order ) {
            return $job['payload']['order_id'] === $order->id;
        } );
        $this->fake->assert_not_pushed( RefundJob::class );
    }

    public function test_bulk_import_dispatches_batch(): void {
        start_bulk_import( $rows );

        $this->fake->assert_batched( function ( array $batch ) use ( $rows ) {
            return count( $batch['jobs'] ) === count( $rows );
        } );
    }

    public function test_nothing_dispatched_without_data(): void {
        process_empty_queue();

        $this->fake->assert_nothing_pushed();
    }
}
```
