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を実装するモック構造体を定義します。このドキュメントではmockallクレートを使用しますが、テストでは別のモック フレームワークを使用できます。モックに期待値を設定し、
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 などのほとんどのクライアントは、スタブトレイトの参照カウント(Arc)dyn 互換実装を内部に保持します。動的ディスパッチを使用して、クライアントから基盤となるスタブにリクエストを転送します。このスタブは、本番環境の実装またはモックのいずれかです。
これらのクライアントは動的ディスパッチを使用するため、コンパイラはコンパイル時に具体的なスタブタイプを解決する必要がなく、クライアント構造体はスタブに汎用型パラメータを必要としません。
Storage クライアント
Rust では、dyn 互換のトレイトにジェネリック メソッドを含めることはできません。また、ボックス化されていない impl Future 値を返すこともできません。
write_object_bufferedメソッドとwrite_object_unbufferedメソッドは、ペイロード ソースタイプに対して汎用的です。gcs::stub::Storageトレイト メソッドは、返された Future をボックス化するのではなく、impl Futureを直接返します。
Storage クライアントに動的ディスパッチを使用すると、呼び出しごとにペイロードとフューチャーをボックス化する必要があり、データパスにヒープ割り当てと動的ディスパッチのオーバーヘッドが追加されます。このオーバーヘッドを回避するため、Storage クライアントは、代わりに gcs::stub::Storage トレイトの具体的な実装に型パラメータを使用します。
完全なアプリケーション コードとテストスイート
次のコードは、アプリケーション関数と単体テストを組み合わせて実証済みの例にしています。
cargo test を実行して test_count_lines と test_upload を実行します。
cargo test