Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rustのテストコード事始め

 Rustのテストコード事始め

More Decks by PharmaX(旧YOJO Technologies)開発チーム

Other Decks in Technology

Transcript

  1. Rust のテストコード事始め 1 Rust のテストコード事始め Rust のテストについて 単体テスト cfg(test) 属性を付与したテスト時のみコンパイルされるモジュールを定義する

    テストとして実行したい関数にtest 属性を付与する テストの中身をassert_eq! やResult を返却することで実装する cargo test を実行する アサーション assert! は、引数がtrue かどうか、assert_eq! は2 つの引数が等価かどうか、assert_ne! は2 つの引数が異なるか どうかを検証する
  2. Rust のテストコード事始め 3 テストの記述場所 これには諸流派あるが、下記の参考記事ではunit テストは対象のあるファイルにそのまま書くことが多いと している Rust でテストコードをどこに書くべきか ##

    質問内容 Rust を最近勉強し始めました。 Rust でテストコードを書きたいのですが、 Rust ではどこにテストコードを書くのがベストプラクティスなのでしょうか?ドキュメン トを見てみると、 https://teratail.com/questions/208572 test フォルダを用意して書いていく派閥も存在する https://github.com/abdolence/firestore-rs
  3. Rust のテストコード事始め 4 やること自体は変わらない テスト用のモジュール mockall Client のモックライブラリとしては、mockall 、fake を使うのが流行りのようだ

    Rust でmock するならmockall で決まり!・・・でよろしいでしょうか? Rust で DI (Dependency Injection) 、してますか?今日話題にするのはドメイン層でインタ ーフェイスを定義してインフラ層でその実装を書くやつです。例えばドメイン層で trait UserRepository を書いて、インフラ層で struct UserRepositoryImpl するやつです。 テス https://laysakura.github.io/2021/04/25/rust-mockall/
  4. Rust のテストコード事始め 5 [Rust] mockall で単体テスト - Qiita ある型A が別の型B

    に依存する場合,型A の単体テストにおいて型B をモック化することが 考えられます.今回はmockall クレートを使って型B のモック化をしてみます.今回説明で 使うディレクトリは以下の構… https://qiita.com/deepgreenAN/items/1b9887db759bbb96c9b6 Rust で構造体をモックする方法を調べる - Qiita はじめにこちらは社内技術勉強会用の資料として作成したものです。Rust で記述されてい るサンプルプログラムにおいて、ジェネリクスによる方法と、mockall を使用する方法の、 2 種類で構造体のモック… https://qiita.com/kagesumi3m/items/aa641b6127bce3d37cd6 [Rust] mockall_double で構造体をモックをする | DevelopersIO mockall_double crate で構造体のモックを手軽に実現できます。しかしモック対象の構造 体のコンストラクタ呼び出しがテストプロファイルだとコンパイルできなくなる点に注意 が必要です。 https://dev.classmethod.jp/articles/mock_structs_with_mockall_double/ テストを実装する|ウェブサービス開発入門 in Rust https://zenn.dev/tkzwhr/books/rust-webapp-tutorial/viewer/test struct やtrait のmock をすることができる cfg_attr を用いてtest のときのみmockall::aoutomock マクロを適用することで、Mock 〇〇型が自動で生成さ れる 下記のようにtest で期待する返却値を設定することで、実際にdb 接続などを行わなくとも返却値を返せるよ うになる
  5. Rust のテストコード事始め 6 derive(Clone) を実装しているstruct はautomock できなので、Clone を実装しているStruct は、下記のように mock!

    で囲む必要がある mock! { pub HttpClient { pub(crate) async fn get_access_token(&self, body: String) -> anyhow::Result<String>; pub(crate) async fn get_folder_items(&self, url: &String, access_token: &String) -> anyhow::Result<String>; pub(crate) async fn post_sms_request(&self, body: String) -> anyhow::Result<String>; pub(crate) async fn download_file(&self, url: &String, access_token: &String) -> anyhow::Result<Vec<u8>>; } impl Clone for HttpClient { fn clone(&self) -> Self; } } なぜかtest 環境だけでderive(Dummy) を有効にしていると、tokio::test ではfake を作成できなかった
  6. Rust のテストコード事始め 7 axum_test axum_test - Rust Axum Test is

    a library for writing tests for web servers written using Axum: https://docs.rs/axum-test/latest/axum_test/index.html# テスト用のサーバーを作成する
  7. Rust のテストコード事始め 8 書き方はTestServer::new の箇所以外は普通のサーバーを作成するのと同じ layer&Extension でmodules を引き渡すことも可能 テスト用のサーバーなので、ホスト名やport を指定する必要はない

    テスト用のサーバーにリクエストするとTestResponse が返ってくるので、TestResponse を検証する let response = server.put("/users") .content_type(&"application/json") .json(&json!({ "username": "Terrance Pencilworth", })) .await; 具体的なStatusCode で検証することが可能 TestResponse in axum_test - Rust The `TestResponse` is the result of a request created using a `TestServer`. The `TestServer` builds a `TestRequest`, which when awaited, will produce this type. https://docs.rs/axum-test/latest/axum_test/struct.TestResponse.html#