

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Unit-Tests mit `aws-smithy-mocks` im AWS SDK für Rust
<a name="testing-smithy-mocks"></a>

Das AWS SDK für Rust bietet mehrere Ansätze zum Testen Ihres Codes, der mit AWS-Services interagiert. In diesem Thema wird beschrieben, wie Sie die [https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/](https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/)Crate verwenden. Sie bietet eine einfache und dennoch leistungsstarke Möglichkeit, Antworten von AWS SDK-Clients zu Testzwecken nachzuahmen.

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

Wenn Sie Tests für Code schreiben, der Use verwendet AWS-Services, möchten Sie häufig vermeiden, tatsächliche Netzwerkaufrufe zu tätigen. Die `aws-smithy-mocks` Crate bietet eine Lösung, indem sie Ihnen Folgendes ermöglicht:
+ Erstellen Sie Scheinregeln, die definieren, wie das SDK auf bestimmte Anfragen reagieren soll.
+ Gibt verschiedene Arten von Antworten zurück (Erfolg, Fehler, HTTP-Antworten).
+ Ordnen Sie Anfragen anhand ihrer Eigenschaften zu.
+ Definieren Sie Antwortsequenzen zum Testen des Wiederholungsverhaltens.
+ Stellen Sie sicher, dass Ihre Regeln wie erwartet verwendet wurden.

## Die Abhängigkeit wird hinzugefügt
<a name="dependency-smithy-mock"></a>

Fügen Sie in einer Befehlszeile für Ihr Projektverzeichnis die [https://crates.io/crates/aws-smithy-mocks](https://crates.io/crates/aws-smithy-mocks)Crate als Abhängigkeit hinzu:

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

Wenn Sie die `--dev` [Option](https://doc.rust-lang.org/cargo/commands/cargo-add.html) verwenden, wird die Kiste dem `[dev-dependencies]` Abschnitt Ihrer `Cargo.toml` Datei hinzugefügt. Da es sich um eine [Entwicklungsabhängigkeit](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies) handelt, wird sie nicht kompiliert und nicht in Ihre endgültige Binärdatei aufgenommen, die für den Produktionscode verwendet wird.

Dieser Beispielcode verwendet auch Amazon Simple Storage Service als AWS-Service Beispiel und erfordert eine Funktion`test-util`.

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

Dadurch wird die Kiste dem `[dependencies]` Abschnitt Ihrer `Cargo.toml` Datei hinzugefügt.

## Grundlegende Verwendung
<a name="basic-smithy-mocks"></a>

 Hier ist ein einfaches Beispiel für die Verwendung `aws-smithy-mocks` zum Testen von Code, der mit Amazon Simple Storage Service (Amazon S3) interagiert:

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

## Scheinregeln erstellen
<a name="creating-rules-smithy-mocks"></a>

Regeln werden mithilfe des `mock!` Makros erstellt, das eine Client-Operation als Argument verwendet. Anschließend können Sie konfigurieren, wie sich die Regel verhalten soll. 

### Passende Anfragen
<a name="matching-requests-smithy-mocks"></a>

 Sie können Regeln spezifischer gestalten, indem Sie Eigenschaften auf Anfrage abgleichen:

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

### Verschiedene Antworttypen
<a name="diff-response-smithy-mocks"></a>

Sie können verschiedene Arten von Antworten zurückgeben:

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

## Verhalten bei Wiederholungsversuchen testen
<a name="testing-retry-behavior-smithy-mocks"></a>

Eine der leistungsstärksten Funktionen von `aws-smithy-mocks` ist die Fähigkeit, das Wiederholungsverhalten zu testen, indem Sequenzen von Antworten definiert werden:

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

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

Mithilfe von Regelmodi können Sie steuern, wie Regeln abgeglichen und angewendet werden:

```
// 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]);
```

## Beispiel: Testen des Wiederholungsverhaltens
<a name="example-retry-smithy-mocks"></a>

Hier ist ein vollständigeres Beispiel, das zeigt, wie das Verhalten bei Wiederholungen getestet wird:

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

## Beispiel: Verschiedene Antworten basierend auf Anforderungsparametern
<a name="example-request-param-smithy-mocks"></a>

Sie können auch Regeln erstellen, die auf der Grundlage von Anforderungsparametern unterschiedliche Antworten zurückgeben:

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

## Best Practices
<a name="best-practices-smithy-mocks"></a>

Bei der Verwendung `aws-smithy-mocks` zum Testen:

1.  Spezifische Anfragen zuordnen: Verwenden Sie diese Option`match_requests()`, um sicherzustellen, dass Ihre Regeln nur für die beabsichtigten Anfragen gelten, insbesondere für`RuleMode:::MatchAny`.

1.  Überprüfen Sie die Regelverwendung: Stellen `rule.num_calls()` Sie sicher, dass Ihre Regeln tatsächlich verwendet wurden.

1.  Testen Sie die Fehlerbehandlung: Erstellen Sie Regeln, die Fehler zurückgeben, um zu testen, wie Ihr Code mit Fehlern umgeht.

1.  Testen Sie die Wiederholungslogik: Verwenden Sie Antwortsequenzen, um zu überprüfen, ob Ihr Code alle benutzerdefinierten Wiederholungsklassifikatoren oder anderes Wiederholungsverhalten korrekt behandelt.

1. Konzentrieren Sie sich auf Tests: Erstellen Sie separate Tests für verschiedene Szenarien, anstatt zu versuchen, alles in einem Test abzudecken.