
# Testovanie

Queuety poskytuje triedu `QueueFake`, ktorá nahrádza skutočný front úložiskom v pamäti. Odoslané úlohy sa zaznamenávajú namiesto zápisu do databázy a `create_batch()` zaznamenáva v pamäti aj metadáta dávok. Vďaka tomu môžete overiť správanie pri odosielaní úloh bez spúšťania workerov alebo zápisu do databázy. Pri odosielaní podľa názvu obslužnej rutiny sa rutina stále vyhľadáva v registri, preto pred odoslaním pomocou reťazca najprv zavolajte `Queuety::init()`; inštancie `Contracts\Job`, `chain()`, `create_batch()` a `batch()` fungujú aj bez toho.

## Nastavenie falošnej implementácie

Zavolajte `Queuety::fake()` na začiatku testu. Vráti inštanciu `QueueFake`, ktorá zaznamenáva všetky nasledujúce odoslané úlohy.

```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()` vytvára novú `QueueFake` a pripája ju k fasáde `Queuety`. `Queuety::dispatch()` a `Dispatchable::dispatch()` zaznamenávajú odoslané úlohy. `Queuety::chain()` zaznamenáva každú úlohu v reťazci ako bežné odoslanie v poradí odoslania. `Queuety::create_batch()` zaznamenáva odoslané úlohy aj metadáta dávky, ktoré používa `assert_batched()`. `Queuety::batch()` zaznamenáva odoslané úlohy, ale nevytvára falošné metadáta dávky.

Zavolajte `Queuety::reset()` v `tearDown()`, aby ste medzi testami vymazali falošnú implementáciu. Vymaže celý stav fasády, takže ak neskorší test potrebuje skutočný front, znova zavolajte `Queuety::init()`.

## Overovanie odoslania úloh

### `assert_pushed()`

Overte, že konkrétna trieda úloh bola odoslaná aspoň raz.

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

Voliteľným spätným volaním môžete filtrovať podľa obsahu alebo iných atribútov. Spätné volanie dostane zaznamenané pole údajov úlohy s kľúčmi `handler`, `payload`, `queue` a `instance`. Pri úlohách odoslaných cez fasádu alebo vlastnosť `Dispatchable` má `instance` hodnotu `null`, preto filtrujte podľa `handler` a `payload`.

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

### `assert_pushed_times()`

Overte, že úloha bola odoslaná presne stanovený počet ráz.

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

### `assert_not_pushed()`

Overte, že úloha nebola nikdy odoslaná.

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

### `assert_nothing_pushed()`

Overte, že nebola odoslaná žiadna ú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();
}
```

## Overovanie dávok

### `assert_batched()`

Overte, že dávka bola odoslaná. Voliteľným spätným volaním môžete filtrovať podľa obsahu dávky.

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

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

Spätné volanie dostane pole s kľúčmi `jobs` a `options`.

## Kontrola odoslaných úloh

Pomocou `pushed()` získate všetky zaznamenané odoslania pre danú triedu a pomocou `batches()` všetky zaznamenané dávky.

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

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

## Resetovanie medzi testami

Zavolaním `reset()` na falošnej implementácii vymažete všetky zaznamenané úlohy a dávky bez vytvorenia novej inštancie.

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

Alebo zavolaním `Queuety::reset()` úplne odstránite falošnú implementáciu aj celý jej interný stav.

## Úplný prí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();
    }
}
```
