
# 테스트

Queuety은 실제 대기열을 메모리 내 저장소로 대체하는 `QueueFake` 클래스를 제공합니다. 전달된 작업은 데이터베이스에 기록되는 대신 저장되며, `create_batch()`도 일괄 처리 메타데이터를 메모리에 기록합니다. 따라서 워커를 실행하거나 데이터베이스에 기록하지 않고도 전달 동작을 확인할 수 있습니다. 핸들러 이름으로 전달할 때는 레지스트리에서 핸들러를 확인하므로, 문자열 핸들러를 전달하려면 먼저 `Queuety::init()`을 호출하세요. `Contracts\Job` 인스턴스, `chain()`, `create_batch()` 및 `batch()`에는 이 호출이 필요하지 않습니다.

## 가짜 대기열 설정

테스트를 시작할 때 `Queuety::fake()`을 호출하세요. 이후의 모든 작업 전달을 기록하는 `QueueFake` 인스턴스가 반환됩니다.

```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()`은 새 `QueueFake`을 만들고 `Queuety` 파사드에 연결합니다. `Queuety::dispatch()` 및 `Dispatchable::dispatch()`는 푸시된 작업을 기록합니다. `Queuety::chain()`는 체인에 포함된 각 작업을 전달 순서대로 일반 푸시 작업으로 기록합니다. `Queuety::create_batch()`은 푸시된 작업과 `assert_batched()`에서 사용하는 일괄 처리 메타데이터를 모두 기록합니다. `Queuety::batch()`은 푸시된 작업을 기록하지만 가짜 일괄 처리 메타데이터는 만들지 않습니다.

테스트 사이에 가짜 대기열을 초기화하려면 `tearDown()`에서 `Queuety::reset()`을 호출하세요. 파사드 상태가 모두 지워지므로, 이후 테스트에서 실제 대기열이 필요하면 `Queuety::init()`를 다시 호출하세요.

## 푸시된 작업 확인

### `assert_pushed()`

특정 작업 클래스가 한 번 이상 전달되었는지 확인합니다.

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

선택적 콜백을 전달해 페이로드나 다른 속성으로 필터링할 수 있습니다. 콜백에는 `handler`, `payload`, `queue` 및 `instance` 키가 있는 기록된 작업 데이터 배열이 전달됩니다. 파사드 또는 `Dispatchable` 트레이트를 통해 전달한 작업에서는 `instance`가 `null`이므로 `handler` 및 `payload`을 기준으로 일치 항목을 찾으세요.

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

### `assert_pushed_times()`

작업이 정확히 지정한 횟수만큼 푸시되었는지 확인합니다.

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

### `assert_not_pushed()`

작업이 한 번도 전달되지 않았는지 확인합니다.

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

### `assert_nothing_pushed()`

작업이 전혀 전달되지 않았는지 확인합니다.

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

## 일괄 처리 확인

### `assert_batched()`

일괄 처리가 전달되었는지 확인합니다. 선택적으로 콜백을 전달해 일괄 처리의 항목을 기준으로 필터링할 수 있습니다.

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

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

콜백에는 `jobs` 및 `options` 키가 있는 배열이 전달됩니다.

## 푸시된 작업 확인하기

특정 클래스에 대해 기록된 모든 작업 전달을 가져오려면 `pushed()`을 사용하고, 기록된 모든 일괄 처리를 가져오려면 `batches()`을 사용하세요.

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

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

## 테스트 사이에 초기화

새 인스턴스를 만들지 않고 기록된 작업 및 일괄 처리를 모두 지우려면 가짜 대기열에서 `reset()`을 호출하세요.

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

또는 가짜 대기열과 모든 내부 상태를 완전히 해제하려면 `Queuety::reset()`을 호출하세요.

## 전체 예시

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