
# Testiranje

Queuety ponuja razred `QueueFake`, ki pravo čakalno vrsto nadomesti s pomnilniško shrambo. Razposlana opravila se zabeležijo, namesto da bi se zapisala v podatkovno zbirko, metapodatke paketov pa v pomnilnik zabeleži tudi `create_batch()`. Tako lahko preverite vedenje pri razpošiljanju, ne da bi zagnali delavce ali zapisovali v podatkovno zbirko. Pri razpošiljanju z imenom obravnavalnika se ta še vedno poišče v registru, zato pri razpošiljanju z nizi najprej pokličite `Queuety::init()`; primerki `Contracts\Job`, `chain()`, `create_batch()` in `batch()` delujejo brez tega.

## Nastavitev ponaredka

Na začetku preizkusa pokličite `Queuety::fake()`. Vrne primerek `QueueFake`, ki beleži vsa nadaljnja razpošiljanja.

```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()` ustvari nov `QueueFake` in ga poveže z vmesnikom `Queuety`. `Queuety::dispatch()` in `Dispatchable::dispatch()` beležita potisnjena opravila. `Queuety::chain()` vsako verižno opravilo zabeleži kot običajno potisnjeno opravilo v vrstnem redu razpošiljanja. `Queuety::create_batch()` beleži potisnjena opravila in metapodatke paketa, ki jih uporablja `assert_batched()`. `Queuety::batch()` beleži potisnjena opravila, vendar ne ustvari ponarejenih metapodatkov paketa.

Med preizkusi pokličite `Queuety::reset()` v `tearDown()`, da počistite ponaredek. Počisti celotno stanje vmesnika, zato znova pokličite `Queuety::init()`, če poznejši preizkus potrebuje pravo čakalno vrsto.

## Preverjanje potisnjenih opravil

### `assert_pushed()`

Preverite, ali je bilo določeno opravilo tega razreda razposlano vsaj enkrat.

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

Podajte neobvezno povratno funkcijo za filtriranje po tovoru ali drugih atributih. Povratna funkcija prejme zabeleženo podatkovno polje opravila s ključi `handler`, `payload`, `queue` in `instance`. `instance` je `null` pri opravilih, razposlanih prek vmesnika ali lastnosti `Dispatchable`, zato uporabite ključa `handler` in `payload`.

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

### `assert_pushed_times()`

Preverite, ali je bilo opravilo potisnjeno točno določeno število krat.

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

### `assert_not_pushed()`

Preverite, ali opravilo ni bilo nikoli razposlano.

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

### `assert_nothing_pushed()`

Preverite, ali sploh ni bilo razposlano nobeno opravilo.

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

## Preverjanje paketov

### `assert_batched()`

Preverite, ali je bil paket razposlan. Po želji podajte povratno funkcijo za filtriranje po vsebini paketa.

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

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

Povratna funkcija prejme polje s ključema `jobs` in `options`.

## Pregled potisnjenih opravil

Z `pushed()` pridobite vsa zabeležena razpošiljanja za dani razred, z `batches()` pa vse zabeležene pakete.

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

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

## Ponastavitev med preizkusi

Pokličite `reset()` na ponaredku, da počistite vsa zabeležena opravila in pakete, ne da bi ustvarili nov primerek.

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

Ali pa pokličite `Queuety::reset()`, da povsem odstranite ponaredek in vse notranje stanje.

## Celoten primer

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