Rust 適用的 Cloud 用戶端程式庫提供一種方法,可虛設常式實際用戶端實作,以便您插入模擬進行測試。您可以使用模擬物件,編寫可控且可靠的單元測試,不會發出網路呼叫或產生費用。
本文將說明下列主題:
- 如何使用 Cloud Storage
Storage用戶端編寫可測試的介面。 - 如何模擬讀取作業。
- 如何模擬寫入作業。
Storage用戶端的設計與其他 Google Cloud用戶端不同的原因。
依附元件
將 Cloud Storage 用戶端程式庫新增至 Cargo.toml 檔案:
cargo add google-cloud-storage
如要編譯並執行本文件中的單元測試,請新增下列開發依附元件:
cargo add --dev anyhow bytes mockall
cargo add --dev tokio --features macros,rt-multi-thread
編寫可測試的介面
如果您不對儲存空間程式碼進行單元測試,可以直接根據 Storage 編寫介面,其預設虛設常式類型參數是用戶端的正式版實作:
如要使用模擬用戶端測試程式碼,請根據受 gcs::stub::Storage + 'static 約束的一般類型參數 T 編寫介面:
模擬讀取作業
如要模擬 read_object 要求,請完成下列步驟:
編寫採用一般
&Storage<T>用戶端的應用程式函式。舉例來說,下列函式會下載物件,並計算其中包含的換行字元數量:建立輔助函式,透過將酬載傳遞至
ReadObjectResponse::from_source,建構假的ReadObjectResponse位元組串流。這個方法接受與Storage::write_object相同的酬載類型:定義實作
gcs::stub::Storage的模擬結構體。本文使用mockallcrate,但您可以在測試中使用其他模擬架構:編寫單元測試,設定模擬物件的預期行為、使用
Storage::from_stub建構用戶端,並呼叫count_newlines:
模擬寫入作業
如要模擬 write_object 要求,請完成下列步驟:
編寫應用程式函式,使用一般
&Storage<T>用戶端上傳物件:使用上一節定義的
MockStorage結構,編寫單元測試,設定模擬物件的預期行為、使用Storage::from_stub建構用戶端,並呼叫upload:
預期詳細資料
由於 upload 函式會呼叫 send_unbuffered,因此請對應的 expect_write_object_unbuffered 方法設定預期:
mockall::mock! 巨集會將每個一般例項化視為不同的方法。在閉包簽章中指定具體酬載類型 Payload<BytesSource>,讓編譯器能比對方法預期:
設計原理
以下各節說明 Storage 用戶端為何使用一般類型參數做為虛設常式,而非動態調度。
其他用戶端
大多數用戶端 (例如 StorageControl) 會在內部保留與 dyn 相容的虛設常式特徵實作,並採用參照計數 (Arc)。它們使用動態調度,將用戶端的要求轉送至底層虛設常式,該虛設常式可以是實際工作環境實作或模擬。
由於這些用戶端使用動態調度,編譯器不需要在編譯時間解析具體虛設常式類型,且用戶端結構體不需要虛設常式的泛型類型參數。
Storage 用戶端
在 Rust 中,與 dyn 相容的特徵不能有泛型方法,也不能傳回未封裝的 impl Future 值:
write_object_buffered和write_object_unbuffered方法是酬載來源類型的泛型。gcs::stub::Storage特徵方法會直接傳回impl Future,而不是將傳回的 Future 裝箱。
如果對 Storage 用戶端使用動態調度,則每次呼叫時都需要對酬載和 Future 進行裝箱,進而增加資料路徑上的堆積分配量和動態調度負擔。為避免這種負擔,Storage 用戶端會改用類型參數,具體實作 gcs::stub::Storage 特徵。
完整的應用程式程式碼和測試套件
下列程式碼將應用程式函式和單元測試結合成已完成樣本:
執行 cargo test,以執行 test_count_lines 和 test_upload:
cargo test