

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在適用於 Rust 的 AWS SDK 中使用靜態重播來模擬 HTTP 流量
<a name="testing-replay"></a>

 適用於 Rust 的 AWS SDK 提供多種方法來測試與 互動的程式碼 AWS 服務。本主題說明如何使用 `StaticReplayClient`建立可使用的仿造 HTTP 用戶端，而非 通常使用的標準 HTTP 用戶端 AWS 服務。此用戶端會傳回您指定的 HTTP 回應，而不是透過網路與服務通訊，以便測試取得已知資料以供測試之用。

`aws-smithy-http-client` 木箱包含名為 的測試公用程式類別[https://docs.rs/aws-smithy-http-client/latest/aws_smithy_http_client/test_util/struct.StaticReplayClient.html](https://docs.rs/aws-smithy-http-client/latest/aws_smithy_http_client/test_util/struct.StaticReplayClient.html)。您可以在建立 AWS 服務 物件時指定此 HTTP 用戶端類別，而非預設的 HTTP 用戶端。

初始化 時`StaticReplayClient`，您會提供 HTTP 請求和回應對的清單做為`ReplayEvent`物件。測試執行時，會記錄每個 HTTP 請求，且用戶端會傳回`ReplayEvent`事件清單中的下一個 HTTP 回應做為 HTTP 用戶端的回應。這可讓測試使用已知資料執行，無需網路連線。

## 使用靜態重播
<a name="testing-replay-steps"></a>

若要使用靜態重播，您不需要使用包裝函式。反之，請判斷測試將使用之資料的實際網路流量看起來應該是什麼樣子，並在每次 SDK 從 AWS 服務 用戶端發出請求時，提供該流量資料給 `StaticReplayClient` 使用。

**注意**  
有幾種方法可以收集預期的網路流量，包括 AWS CLI 和許多網路流量分析器和封包偵測器工具。
+ 建立指定預期 HTTP 請求的`ReplayEvent`物件清單，以及應為其傳回的回應。
+ `StaticReplayClient` 使用上一個步驟中建立的 HTTP 交易清單來建立 。
+ 為 AWS 用戶端建立組態物件，將 指定`StaticReplayClient`為`Config`物件的 `http_client`。
+ 使用上一個步驟中建立的組態來建立 AWS 服務 用戶端物件。
+ 使用設定為使用 的服務物件，執行您要測試的操作`StaticReplayClient`。每次開發套件傳送 API 請求時 AWS，都會使用清單中的下一個回應。
**注意**  
即使傳送的請求與`ReplayEvent`物件向量中的回應不相符，一律會傳回清單中的下一個回應。
+ 完成所有所需的請求後，請呼叫 `StaticReplayClient.assert_requests_match()`函數，確認 SDK 傳送的請求符合`ReplayEvent`物件清單中的請求。

## 範例
<a name="testing-replay-example"></a>

讓我們看看先前範例中相同`determine_prefix_file_size()`函數的測試，但使用靜態重播而非模擬。

1. 在專案目錄的命令提示中，新增[https://crates.io/crates/aws-smithy-http-client](https://crates.io/crates/aws-smithy-http-client)木箱做為相依性：

   ```
   $ cargo add --dev aws-smithy-http-client --features test-util
   ```

   使用 `--dev`[選項](https://doc.rust-lang.org/cargo/commands/cargo-add.html)將木箱新增至 `Cargo.toml` 檔案的 `[dev-dependencies]`區段。作為[開發相依性](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#development-dependencies)，它不會編譯並包含在用於生產程式碼的最終二進位檔中。

   此範例程式碼也會使用 Amazon Simple Storage Service 做為範例 AWS 服務。

   ```
   $ cargo add aws-sdk-s3
   ```

   這會將 木箱新增至 `Cargo.toml` 檔案的 `[dependencies]`區段。

1. 在您的測試程式碼模組中，包含您需要的兩種類型。

   ```
   use aws_smithy_http_client::test_util::{ReplayEvent, StaticReplayClient};
   use aws_sdk_s3::primitives::SdkBody;
   ```

1. 測試一開始會建立`ReplayEvent`結構，代表測試期間應進行的每個 HTTP 交易。每個事件都包含 HTTP 請求物件和 HTTP 回應物件，代表 AWS 服務 通常會回覆的資訊。這些事件會傳遞給 的呼叫`StaticReplayClient::new()`：

   ```
           let page_1 = ReplayEvent::new(
                   http::Request::builder()
                       .method("GET")
                       .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix")
                       .body(SdkBody::empty())
                       .unwrap(),
                   http::Response::builder()
                       .status(200)
                       .body(SdkBody::from(include_str!("./testing/response_multi_1.xml")))
                       .unwrap(),
               );
           let page_2 = ReplayEvent::new(
                   http::Request::builder()
                       .method("GET")
                       .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix&continuation-token=next")
                       .body(SdkBody::empty())
                       .unwrap(),
                   http::Response::builder()
                       .status(200)
                       .body(SdkBody::from(include_str!("./testing/response_multi_2.xml")))
                       .unwrap(),
               );
           let replay_client = StaticReplayClient::new(vec![page_1, page_2]);
   ```

   結果會存放在 中`replay_client`。這表示 HTTP 用戶端，然後可在用戶端的組態中指定 Rust 開發套件來使用。

1. 若要建立 Amazon S3 用戶端，請呼叫用戶端類別的 `from_conf()`函數，以使用組態物件建立用戶端：

   ```
           let client: s3::Client = s3::Client::from_conf(
               s3::Config::builder()
                   .behavior_version(BehaviorVersion::latest())
                   .credentials_provider(make_s3_test_credentials())
                   .region(s3::config::Region::new("us-east-1"))
                   .http_client(replay_client.clone())
                   .build(),
           );
   ```

   組態物件是使用建置器的 `http_client()`方法指定，而登入資料是使用 `credentials_provider()`方法指定。登入資料是使用名為 的函數建立`make_s3_test_credentials()`，其會傳回仿造登入資料結構：

   ```
   fn make_s3_test_credentials() -> s3::config::Credentials {
       s3::config::Credentials::new(
           "ATESTCLIENT",
           "astestsecretkey",
           Some("atestsessiontoken".to_string()),
           None,
           "",
       )
   }
   ```

   這些登入資料不需要有效，因為它們實際上不會傳送到 AWS。

1. 呼叫需要測試的 函數來執行測試。在此範例中，該函數的名稱為 `determine_prefix_file_size()`。其第一個參數是用於其請求的 Amazon S3 用戶端物件。因此，指定使用 建立的用戶端，`StaticReplayClient`讓請求由該用戶端處理，而不是透過網路傳出：

   ```
           let size = determine_prefix_file_size(client, "test-bucket", "test-prefix")
               .await
               .unwrap();
   
           assert_eq!(19, size);
   
           replay_client.assert_requests_match(&[]);
   ```

   對 的呼叫`determine_prefix_file_size()`完成時，會使用宣告來確認傳回的值符合預期值。然後，呼叫 `StaticReplayClient`方法`assert_requests_match()`函數。此函數會掃描記錄的 HTTP 請求，並確認它們都符合建立重播用戶端時所提供`ReplayEvent`物件陣列中指定的請求。

您可以在 GitHub 上[檢視這些範例的完整程式碼](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1/examples/testing)。