
# Pengujian

Queuety menyediakan kelas `QueueFake` yang menggantikan antrean sebenarnya dengan penyimpanan dalam memori. Job yang di-dispatch dicatat alih-alih ditulis ke basis data, dan `create_batch()` juga mencatat metadata batch dalam memori. Dengan demikian, Anda dapat memeriksa perilaku dispatch tanpa menjalankan worker atau menulis ke basis data. Dispatch berdasarkan nama handler tetap mencari handler melalui registry, jadi panggil `Queuety::init()` terlebih dahulu untuk dispatch dengan handler berupa string; instance `Contracts\Job`, `chain()`, `create_batch()`, dan `batch()` dapat digunakan tanpa itu.

## Menyiapkan antrean palsu

Panggil `Queuety::fake()` di awal pengujian. Fungsi ini mengembalikan instance `QueueFake` yang mencatat semua dispatch berikutnya.

```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()` membuat `QueueFake` baru dan menghubungkannya ke facade `Queuety`. `Queuety::dispatch()` dan `Dispatchable::dispatch()` mencatat job yang didorong ke antrean. `Queuety::chain()` mencatat setiap job berantai sebagai push biasa sesuai urutan dispatch. `Queuety::create_batch()` mencatat job yang didorong beserta metadata batch yang digunakan oleh `assert_batched()`. `Queuety::batch()` mencatat job yang didorong, tetapi tidak membuat metadata batch palsu.

Panggil `Queuety::reset()` di `tearDown()` untuk mengosongkan antrean palsu di antara pengujian. Fungsi ini menghapus seluruh status facade, jadi panggil `Queuety::init()` lagi jika pengujian berikutnya memerlukan antrean sebenarnya.

## Memastikan job telah didorong ke antrean

### `assert_pushed()`

Pastikan kelas job tertentu telah di-dispatch setidaknya sekali.

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

Berikan callback opsional untuk memfilter berdasarkan payload atau atribut lainnya. Callback menerima array data job tercatat dengan kunci `handler`, `payload`, `queue`, dan `instance`. Nilai `instance` adalah `null` untuk job yang di-dispatch melalui facade atau trait `Dispatchable`, jadi cocokkan berdasarkan `handler` dan `payload`.

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

### `assert_pushed_times()`

Pastikan sebuah job didorong ke antrean sebanyak jumlah tertentu.

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

### `assert_not_pushed()`

Pastikan sebuah job tidak pernah di-dispatch.

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

### `assert_nothing_pushed()`

Pastikan tidak ada job yang di-dispatch sama sekali.

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

## Memastikan batch telah di-dispatch

### `assert_batched()`

Pastikan sebuah batch telah di-dispatch. Anda dapat memberikan callback untuk memfilter isi batch.

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

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

Callback menerima array dengan kunci `jobs` dan `options`.

## Memeriksa job yang didorong ke antrean

Gunakan `pushed()` untuk mengambil semua dispatch tercatat untuk kelas tertentu, dan `batches()` untuk mengambil semua batch yang tercatat.

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

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

## Mengatur ulang di antara pengujian

Panggil `reset()` pada antrean palsu untuk menghapus semua job dan batch tercatat tanpa membuat instance baru.

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

Atau panggil `Queuety::reset()` untuk membongkar antrean palsu beserta semua status internal sepenuhnya.

## Contoh lengkap

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