
# Testování

Queuety poskytuje třídu `QueueFake`, která nahrazuje skutečnou frontu úložištěm v paměti. Odeslané úlohy se zaznamenávají místo zápisu do databáze a `create_batch()` ukládá do paměti také metadata dávek. Díky tomu můžete ověřit chování při odesílání úloh bez spouštění workerů nebo zápisu do databáze. Při odesílání podle názvu obslužné rutiny se tato stále vyhledává v registru, proto u odesílání s řetězcovým názvem nejprve zavolejte `Queuety::init()`; instance `Contracts\Job`, `chain()`, `create_batch()` a `batch()` to nevyžadují.

## Nastavení falešné implementace

Na začátku testu zavolejte `Queuety::fake()`. Vrátí instanci `QueueFake`, která zaznamenává všechna následná odeslání.

```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()` vytvoří novou instanci `QueueFake` a propojí ji s fasádou `Queuety`. `Queuety::dispatch()` a `Dispatchable::dispatch()` zaznamenávají přidané úlohy. `Queuety::chain()` zaznamenává každou řetězenou úlohu jako běžné přidání v pořadí odeslání. `Queuety::create_batch()` zaznamenává přidané úlohy i metadata dávky používaná službou `assert_batched()`. `Queuety::batch()` zaznamenává přidané úlohy, ale nevytváří falešná metadata dávky.

Mezi testy zavolejte `Queuety::reset()` v `tearDown()`, aby se falešná implementace vymazala. Vymaže veškerý stav fasády, takže pokud pozdější test potřebuje skutečnou frontu, zavolejte znovu `Queuety::init()`.

## Ověření přidání úloh

### `assert_pushed()`

Ověřte, že byla alespoň jednou odeslána úloha konkrétní třídy.

```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 );
}
```

Předejte volitelnou funkci zpětného volání, která vyfiltruje data nebo jiné atributy. Funkce obdrží pole zaznamenaných dat úlohy s klíči `handler`, `payload`, `queue` a `instance`. U úloh odeslaných přes fasádu nebo vlastnost `Dispatchable` má `instance` hodnotu `null`, proto porovnávejte `handler` a `payload`.

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

### `assert_pushed_times()`

Ověřte, že byla úloha přidána přesně stanovený početkrát.

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

### `assert_not_pushed()`

Ověřte, že úloha nebyla nikdy odeslána.

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

### `assert_nothing_pushed()`

Ověřte, že nebyla odeslána vůbec žádná úloha.

```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();
}
```

## Ověření dávek

### `assert_batched()`

Ověřte, že byla odeslána dávka. Volitelně předejte funkci zpětného volání pro filtrování podle obsahu dávky.

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

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

Funkce zpětného volání obdrží pole s klíči `jobs` a `options`.

## Kontrola přidaných úloh

Pomocí `pushed()` načtěte všechna zaznamenaná odeslání pro danou třídu a pomocí `batches()` načtěte všechny zaznamenané dávky.

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

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

## Resetování mezi testy

Zavolejte na falešné implementaci `reset()`, aby se bez vytvoření nové instance vymazaly všechny zaznamenané úlohy a dávky.

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

Nebo zavolejte `Queuety::reset()`, čímž falešnou implementaci a veškerý její interní stav úplně odstraníte.

## Úplný příklad

```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();
    }
}
```
