

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Tests unitaires avec `aws-smithy-mocks` le AWS SDK pour Rust
<a name="testing-smithy-mocks"></a>

 AWS SDK pour Rust Il fournit plusieurs approches pour tester votre code qui interagit avec Services AWS. Cette rubrique décrit comment utiliser le [https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/](https://docs.rs/aws-smithy-mocks/latest/aws_smithy_mocks/)crate, qui offre un moyen simple mais puissant de simuler les réponses des clients du AWS SDK à des fins de test.

## Présentation de
<a name="overview-smithy-mock"></a>

Lorsque vous rédigez des tests pour du code utilisé Services AWS, vous souhaitez souvent éviter de passer de véritables appels réseau. La `aws-smithy-mocks` caisse apporte une solution en vous permettant de :
+ Créez des règles fictives qui définissent la manière dont le SDK doit répondre à des demandes spécifiques.
+ Renvoie différents types de réponses (succès, erreur, réponses HTTP).
+ Faites correspondre les demandes en fonction de leurs propriétés.
+ Définissez des séquences de réponses pour tester le comportement des nouvelles tentatives.
+ Vérifiez que vos règles ont été utilisées comme prévu.

## Ajouter la dépendance
<a name="dependency-smithy-mock"></a>

Dans une invite de commande pour le répertoire de votre projet, ajoutez le [https://crates.io/crates/aws-smithy-mocks](https://crates.io/crates/aws-smithy-mocks)crate en tant que dépendance :

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

L'utilisation de `--dev` [cette option](https://doc.rust-lang.org/cargo/commands/cargo-add.html) ajoute la caisse à la `[dev-dependencies]` section de votre `Cargo.toml` fichier. En tant que [dépendance de développement](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies), elle n'est pas compilée et incluse dans votre binaire final utilisé pour le code de production.

Cet exemple de code utilise également Amazon Simple Storage Service comme exemple Service AWS et nécessite une fonctionnalité`test-util`.

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

Cela ajoute la caisse à la `[dependencies]` section de votre `Cargo.toml` fichier.

## Utilisation de base
<a name="basic-smithy-mocks"></a>

 Voici un exemple simple de test du code qui interagit avec Amazon Simple Storage Service (Amazon S3) : `aws-smithy-mocks`

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

## Création de règles fictives
<a name="creating-rules-smithy-mocks"></a>

Les règles sont créées à l'aide de la `mock!` macro, qui prend une opération client comme argument. Vous pouvez ensuite configurer le comportement de la règle. 

### Demandes correspondantes
<a name="matching-requests-smithy-mocks"></a>

 Vous pouvez définir des règles plus spécifiques en faisant correspondre les propriétés sur demande :

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

### Différents types de réponses
<a name="diff-response-smithy-mocks"></a>

Vous pouvez renvoyer différents types de réponses :

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

## Tester le comportement des nouvelles tentatives
<a name="testing-retry-behavior-smithy-mocks"></a>

L'une des fonctionnalités les plus puissantes de `aws-smithy-mocks` est la possibilité de tester le comportement des nouvelles tentatives en définissant des séquences de réponses :

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

## Modes de règles
<a name="rule-modes-smithy-mocks"></a>

Vous pouvez contrôler la façon dont les règles sont mises en correspondance et appliquées à l'aide des modes de règles :

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

## Exemple : test du comportement en cas de nouvelle tentative
<a name="example-retry-smithy-mocks"></a>

Voici un exemple plus complet montrant comment tester le comportement des nouvelles tentatives :

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

## Exemple : différentes réponses en fonction des paramètres de la demande
<a name="example-request-param-smithy-mocks"></a>

Vous pouvez également créer des règles qui renvoient différentes réponses en fonction des paramètres de la demande :

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

## Bonnes pratiques
<a name="best-practices-smithy-mocks"></a>

Lors de l'utilisation à `aws-smithy-mocks` des fins de test :

1.  Répondre à des demandes spécifiques : `match_requests()` à utiliser pour vous assurer que vos règles ne s'appliquent qu'aux demandes prévues, en particulier avec`RuleMode:::MatchAny`.

1.  Vérifiez l'utilisation des règles : vérifiez `rule.num_calls()` que vos règles ont été réellement utilisées.

1.  Gestion des erreurs de test : créez des règles renvoyant des erreurs afin de tester la manière dont votre code gère les défaillances.

1.  Testez la logique des nouvelles tentatives : utilisez des séquences de réponses pour vérifier que votre code gère correctement les classificateurs de nouvelles tentatives personnalisés ou tout autre comportement de nouvelle tentative.

1. Concentrez-vous sur les tests : créez des tests distincts pour différents scénarios plutôt que d'essayer de tout couvrir en un seul test.