
# Testowanie

Queuety udostępnia klasę `QueueFake`, która zastępuje właściwą kolejkę magazynem w pamięci. Zamiast zapisywać zadania w bazie danych, zapisuje je jako wysłane, a `create_batch()` również przechowuje metadane grup zadań w pamięci. Dzięki temu możesz sprawdzać zachowanie wysyłania zadań bez uruchamiania workerów ani zapisywania danych w bazie. Wysyłanie zadań według nazwy handlera nadal rozwiązuje handler przez rejestr, dlatego przed wysłaniem zadania z handlerem w postaci ciągu znaków wywołaj `Queuety::init()`; obiekty `Contracts\Job`, `chain()`, `create_batch()` i `batch()` działają bez tego wywołania.

## Konfiguracja atrapy

Wywołaj `Queuety::fake()` na początku testu. Zwraca instancję `QueueFake`, która rejestruje wszystkie kolejne wysłane zadania.

```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()` tworzy nowy `QueueFake` i podłącza go do fasady `Queuety`. `Queuety::dispatch()` i `Dispatchable::dispatch()` zapisują wysłane zadania. `Queuety::chain()` zapisuje każde zadanie w łańcuchu jak zwykłe zadanie, zgodnie z kolejnością wysyłania. `Queuety::create_batch()` zapisuje zarówno wysłane zadania, jak i metadane grupy zadań używane przez `assert_batched()`. `Queuety::batch()` zapisuje wysłane zadania, ale nie tworzy atrapowych metadanych grup zadań.

Wywołaj `Queuety::reset()` w `tearDown()`, aby wyczyścić atrapę między testami. Czyści cały stan fasady, więc wywołaj ponownie `Queuety::init()`, jeśli kolejny test wymaga prawdziwej kolejki.

## Sprawdzanie, czy zadania zostały wysłane

### `assert_pushed()`

Sprawdź, czy zadanie określonej klasy zostało wysłane co najmniej 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 );
}
```

Przekaż opcjonalną funkcję zwrotną, aby filtrować według ładunku lub innych atrybutów. Funkcja otrzymuje tablicę zarejestrowanych danych zadania z kluczami `handler`, `payload`, `queue` i `instance`. `instance` ma wartość `null` w przypadku zadań wysłanych przez fasadę lub cechę `Dispatchable`, dlatego sprawdzaj `handler` i `payload`.

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

### `assert_pushed_times()`

Sprawdź, czy zadanie zostało wysłane dokładnie określoną liczbę razy.

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

### `assert_not_pushed()`

Sprawdź, czy zadanie nie zostało wysłane ani razu.

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

### `assert_nothing_pushed()`

Sprawdź, czy w ogóle nie wysłano żadnych zadań.

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

## Sprawdzanie grup zadań

### `assert_batched()`

Sprawdź, czy grupa zadań została wysłana. Opcjonalnie przekaż funkcję zwrotną, aby filtrować według zawartości grupy.

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

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

Funkcja zwrotna otrzymuje tablicę z kluczami `jobs` i `options`.

## Sprawdzanie wysłanych zadań

Użyj `pushed()`, aby pobrać wszystkie zarejestrowane wysłane zadania danej klasy, a `batches()`, aby pobrać wszystkie zarejestrowane grupy zadań.

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

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

## Resetowanie między testami

Wywołaj `reset()` na atrapie, aby wyczyścić wszystkie zarejestrowane zadania i grupy zadań bez tworzenia nowej instancji.

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

Możesz też wywołać `Queuety::reset()`, aby całkowicie zlikwidować atrapę i wyczyścić cały jej stan wewnętrzny.

## Pełny przykład

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