

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Pengujian unit `aws-smithy-mocks` dengan AWS SDK untuk Rust
<a name="testing-smithy-mocks"></a>

 AWS SDK for Rust Ini menyediakan beberapa pendekatan untuk menguji kode Anda yang berinteraksi dengannya Layanan AWS. Topik ini menjelaskan cara menggunakan [https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/](https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/)peti, yang menawarkan cara sederhana namun ampuh untuk mengejek respons klien AWS SDK untuk tujuan pengujian.

## Ikhtisar
<a name="overview-smithy-mock"></a>

Saat menulis tes untuk kode yang digunakan Layanan AWS, Anda sering ingin menghindari melakukan panggilan jaringan yang sebenarnya. `aws-smithy-mocks`Peti memberikan solusi dengan memungkinkan Anda untuk:
+ Buat aturan tiruan yang menentukan bagaimana SDK harus merespons permintaan tertentu.
+ Kembalikan berbagai jenis tanggapan (sukses, kesalahan, respons HTTP).
+ Permintaan kecocokan berdasarkan properti mereka.
+ Tentukan urutan respons untuk menguji perilaku coba lagi.
+ Verifikasi bahwa aturan Anda digunakan seperti yang diharapkan.

## Menambahkan ketergantungan
<a name="dependency-smithy-mock"></a>

Dalam prompt perintah untuk direktori proyek Anda, tambahkan [https://crates.io/crates/aws-smithy-mocks](https://crates.io/crates/aws-smithy-mocks)peti sebagai dependensi:

```
$ cargo add --dev aws-smithy-mocks
```

Menggunakan `--dev` [opsi](https://doc.rust-lang.org/cargo/commands/cargo-add.html) menambahkan peti ke `[dev-dependencies]` bagian `Cargo.toml` file Anda. Sebagai [dependensi pengembangan](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies), itu tidak dikompilasi dan dimasukkan ke dalam biner akhir Anda yang digunakan untuk kode produksi.

Kode contoh ini juga menggunakan Amazon Simple Storage Service sebagai contoh Layanan AWS, dan memerlukan fitur`test-util`.

```
$ cargo add aws-sdk-s3 --features test-util
```

Ini menambahkan peti ke `[dependencies]` bagian `Cargo.toml` file Anda.

## Penggunaan dasar
<a name="basic-smithy-mocks"></a>

 Berikut adalah contoh sederhana cara menggunakan `aws-smithy-mocks` untuk menguji kode yang berinteraksi dengan Amazon Simple Storage Service (Amazon S3):

```
use aws_sdk_s3::operation::get_object::GetObjectOutput;
use aws_sdk_s3::primitives::ByteStream;
use aws_smithy_mocks::{mock, mock_client};

#[tokio::test]
async fn test_s3_get_object() {
    // Create a rule that returns a successful response
    let get_object_rule = mock!(aws_sdk_s3::Client::get_object)
        .then_output(|| {
            GetObjectOutput::builder()
                .body(ByteStream::from_static(b"test-content"))
                .build()
        });

    // Create a mocked client with the rule
    let s3 = mock_client!(aws_sdk_s3, [&get_object_rule]);

    // Use the client as you would normally
    let result = s3
        .get_object()
        .bucket("test-bucket")
        .key("test-key")
        .send()
        .await
        .expect("success response");

    // Verify the response
    let data = result.body.collect().await.expect("successful read").to_vec();
    assert_eq!(data, b"test-content");

    // Verify the rule was used
    assert_eq!(get_object_rule.num_calls(), 1);
}
```

## Membuat aturan tiruan
<a name="creating-rules-smithy-mocks"></a>

Aturan dibuat menggunakan `mock!` makro, yang mengambil operasi klien sebagai argumen. Anda kemudian dapat mengonfigurasi bagaimana aturan seharusnya berperilaku. 

### Permintaan yang Cocokan
<a name="matching-requests-smithy-mocks"></a>

 Anda dapat membuat aturan lebih spesifik dengan mencocokkan properti berdasarkan permintaan:

```
let rule = mock!(Client::get_object)
    .match_requests(|req| req.bucket() == Some("test-bucket") && req.key() == Some("test-key"))
    .then_output(|| {
        GetObjectOutput::builder()
            .body(ByteStream::from_static(b"test-content"))
            .build()
    });
```

### Jenis Respons yang Berbeda
<a name="diff-response-smithy-mocks"></a>

Anda dapat mengembalikan berbagai jenis tanggapan:

```
// Return a successful response
let success_rule = mock!(Client::get_object)
    .then_output(|| GetObjectOutput::builder().build());

// Return an error
let error_rule = mock!(Client::get_object)
    .then_error(|| GetObjectError::NoSuchKey(NoSuchKey::builder().build()));

// Return a specific HTTP response
let http_rule = mock!(Client::get_object)
    .then_http_response(|| {
        HttpResponse::new(
            StatusCode::try_from(503).unwrap(),
            SdkBody::from("service unavailable")
        )
    });
```

## Menguji perilaku coba lagi
<a name="testing-retry-behavior-smithy-mocks"></a>

Salah satu fitur yang paling kuat `aws-smithy-mocks` adalah kemampuan untuk menguji perilaku coba lagi dengan mendefinisikan urutan tanggapan:

```
// Create a rule that returns 503 twice, then succeeds
let retry_rule = mock!(aws_sdk_s3::Client::get_object)
    .sequence()
    .http_status(503, None)                          // First call returns 503
    .http_status(503, None)                          // Second call returns 503
    .output(|| GetObjectOutput::builder().build())   // Third call succeeds
    .build();

// With repetition using times()
let retry_rule = mock!(Client::get_object)
    .sequence()
    .http_status(503, None)
    .times(2)                                        // First two calls return 503
    .output(|| GetObjectOutput::builder().build())   // Third call succeeds
    .build();
```

## Mode aturan
<a name="rule-modes-smithy-mocks"></a>

Anda dapat mengontrol bagaimana aturan dicocokkan dan diterapkan menggunakan mode aturan:

```
// Sequential mode: Rules are tried in order, and when a rule is exhausted, the next rule is used
let client = mock_client!(aws_sdk_s3, RuleMode::Sequential, [&rule1, &rule2]);

// MatchAny mode: The first matching rule is used, regardless of order
let client = mock_client!(aws_sdk_s3, RuleMode::MatchAny, [&rule1, &rule2]);
```

## Contoh: Menguji perilaku coba lagi
<a name="example-retry-smithy-mocks"></a>

Berikut adalah contoh yang lebih lengkap yang menunjukkan cara menguji perilaku coba lagi:

```
use aws_sdk_s3::operation::get_object::GetObjectOutput;
use aws_sdk_s3::config::RetryConfig;
use aws_sdk_s3::primitives::ByteStream;
use aws_smithy_mocks::{mock, mock_client, RuleMode};

#[tokio::test]
async fn test_retry_behavior() {
    // Create a rule that returns 503 twice, then succeeds
    let retry_rule = mock!(aws_sdk_s3::Client::get_object)
        .sequence()
        .http_status(503, None)
        .times(2)
        .output(|| GetObjectOutput::builder()
            .body(ByteStream::from_static(b"success"))
            .build())
        .build();

    // Create a mocked client with the rule and custom retry configuration
    let s3 = mock_client!(
        aws_sdk_s3,
        RuleMode::Sequential,
        [&retry_rule],
        |client_builder| {
            client_builder.retry_config(RetryConfig::standard().with_max_attempts(3))
        }
    );

    // This should succeed after two retries
    let result = s3
        .get_object()
        .bucket("test-bucket")
        .key("test-key")
        .send()
        .await
        .expect("success after retries");

    // Verify the response
    let data = result.body.collect().await.expect("successful read").to_vec();
    assert_eq!(data, b"success");

    // Verify all responses were used
    assert_eq!(retry_rule.num_calls(), 3);
}
```

## Contoh: Respons berbeda berdasarkan parameter permintaan
<a name="example-request-param-smithy-mocks"></a>

Anda juga dapat membuat aturan yang menampilkan respons berbeda berdasarkan parameter permintaan:

```
use aws_sdk_s3::operation::get_object::{GetObjectOutput, GetObjectError};
use aws_sdk_s3::types::error::NoSuchKey;
use aws_sdk_s3::Client;
use aws_sdk_s3::primitives::ByteStream;
use aws_smithy_mocks::{mock, mock_client, RuleMode};

#[tokio::test]
async fn test_different_responses() {
    // Create rules for different request parameters
    let exists_rule = mock!(Client::get_object)
        .match_requests(|req| req.bucket() == Some("test-bucket") && req.key() == Some("exists"))
        .sequence()
        .output(|| GetObjectOutput::builder()
            .body(ByteStream::from_static(b"found"))
            .build())
        .build();

    let not_exists_rule = mock!(Client::get_object)
        .match_requests(|req| req.bucket() == Some("test-bucket") && req.key() == Some("not-exists"))
        .sequence()
        .error(|| GetObjectError::NoSuchKey(NoSuchKey::builder().build()))
        .build();

    // Create a mocked client with the rules in MatchAny mode
    let s3 = mock_client!(aws_sdk_s3, RuleMode::MatchAny, [&exists_rule, &not_exists_rule]);

    // Test the "exists" case
    let result1 = s3
        .get_object()
        .bucket("test-bucket")
        .key("exists")
        .send()
        .await
        .expect("object exists");

    let data = result1.body.collect().await.expect("successful read").to_vec();
    assert_eq!(data, b"found");

    // Test the "not-exists" case
    let result2 = s3
        .get_object()
        .bucket("test-bucket")
        .key("not-exists")
        .send()
        .await;

    assert!(result2.is_err());
    assert!(matches!(result2.unwrap_err().into_service_error(),
                    GetObjectError::NoSuchKey(_)));
}
```

## Praktik terbaik
<a name="best-practices-smithy-mocks"></a>

Saat menggunakan `aws-smithy-mocks` untuk pengujian:

1.  Cocokkan permintaan khusus: Gunakan `match_requests()` untuk memastikan aturan Anda hanya berlaku untuk permintaan yang dimaksud, khususnya dengan`RuleMode:::MatchAny`.

1.  Verifikasi penggunaan aturan: Periksa `rule.num_calls()` untuk memastikan aturan Anda benar-benar digunakan.

1.  Penanganan kesalahan pengujian: Buat aturan yang mengembalikan kesalahan untuk menguji bagaimana kode Anda menangani kegagalan.

1.  Uji logika coba lagi: Gunakan urutan respons untuk memverifikasi bahwa kode Anda menangani pengklasifikasi coba ulang kustom atau perilaku coba lagi lainnya dengan benar.

1. Tetap fokus pengujian: Buat tes terpisah untuk skenario yang berbeda daripada mencoba mencakup semuanya dalam satu pengujian.