Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Mocking in Rust Applications
Search
taiki45
September 10, 2024
Technology
780
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Mocking in Rust Applications
Talk at "RustのWebアプリ開発 LT道場 〜テスト編〜"
https://findy.connpass.com/event/327824/
taiki45
September 10, 2024
More Decks by taiki45
See All by taiki45
Error Handling in Rust Applications
taiki45
3
870
Efficient Platform for Security and Compliance
taiki45
6
1.7k
RustでAWS Lambda functionをいい感じに書く
taiki45
2
870
SPIFFE Meetup Tokyo #2 LT: Envoy SDS
taiki45
0
860
builderscon Tokyo 2019: Intro Service Mesh
taiki45
6
3.8k
NoOps Meetup Tokyo #7: 入門サービスメッシュ
taiki45
4
2k
CloudNative Days Tokyo 2019: Understanding Envoy
taiki45
3
3.7k
Cloud Native Meetup Tokyo #8 ServiceMesh Day Recap
taiki45
2
440
EnvoyCon 2018: Building and operating service mesh at mid-size company
taiki45
3
4.6k
Other Decks in Technology
See All in Technology
KiCAD講習会②
tutcreators
0
110
SRE Next 2026 何でも屋からの脱却
bto
0
630
SRE本の知られざる名シーン / The Hidden Gems of Google SRE Book
nari_ex
1
370
プロンプト_きのこカンファレンス2026_LT
yurufuwahealer
0
150
AI時代のエンジニアキャリアについて今一度考える
sakamoto_582
2
1.5k
脱金融のフューチャー・デザイン / Future Design Beyond Finance
ks91
PRO
0
150
DMM.com 購入改善推進チーム におけるCodeRabbitを用いた レビューフロー改善の一例
ysknsid25
2
620
最近評価が難しくなった
maroon8021
0
340
環境凍結という Toil を倒す -セルフサービス型 Ephemeral テスト環境の 設計と実践
shirouz
1
2.3k
ソニー銀行におけるビジネスアジリティ向上のためのクラウドシフト戦略
srenext
0
150
プロダクトだけじゃない、社内プロセスにおける自動化・省力化ノススメ
kakehashi
PRO
1
3.6k
SREとQA 二人三脚で進めるSLO運用/sre-qa-slo
sugitak
0
450
Featured
See All Featured
Faster Mobile Websites
deanohume
310
32k
Exploring anti-patterns in Rails
aemeredith
3
440
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
420
How to train your dragon (web standard)
notwaldorf
97
6.7k
We Are The Robots
honzajavorek
0
270
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.3k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
190
Making Projects Easy
brettharned
120
6.7k
AI: The stuff that nobody shows you
jnunemaker
PRO
8
820
What's in a price? How to price your products and services
michaelherold
247
13k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
280
Transcript
© 2024 Finatext Holdings Ltd. Mocking in Rust Applications Taiki
Ono, Finatext
© 2024 Finatext Holdings Ltd. Taiki Ono @taiki45 1
None
© 2024 Finatext Holdings Ltd. 1. モックするまでの道のり 2. モックを定義する・使う 例として使ったコードは
https://github.com/Finatext/orgu に全貌あります 今回の話は単体テストくらいの粒度のテストをスコープにしています 目次 3
© 2024 Finatext Holdings Ltd. モックするまでの道のり 4
© 2024 Finatext Holdings Ltd. テスト対象のロジックは外部依存について差し替え可能であることが望ましいです(後述) Rustでは交換可能性はGenericsまたはTrait Objectsを使って実現できます • Generics
(+ Trait Bounds): コンパイル時に具体的な型が分かるケースで利用します。コンパイラがそれぞ れの具体的な型用のコードを生成する。静的ディスパッチ • Trait Objects: コンパイル時に具体的な型が分からないケースで利用します。実行時のメソッド呼び出し時 に仮想関数テーブルを参照して実際の呼び出し関数(メソッド)を決定します。動的ディスパッチ 交換可能性を導入する 5
© 2024 Finatext Holdings Ltd. 非同期ジョブのロジックという例: 「GitHub Checks APIを使ってCheckRunを作成して、Git cloneでリポジトリをクローンして、指定された外部
コマンドを実行する」 テスト時にモックしたい部分 • GitHub APIを呼ぶ: GithubClient trait • Git clone: Checkout trait →このケースでは例えば、Handlerという構造体を定義してそれぞれの外部依存を持たせる 交換可能性の例 6
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: GithubClient trait 7
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: Checkout trait 8
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: Handler 9
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: Handlerの初期化関数 10
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: ドメインロジック 11
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: 初期化 12
© 2024 Finatext Holdings Ltd. 静的ディスパッチのアプローチ: テスト時の初期化 13
© 2024 Finatext Holdings Ltd. 動的ディスパッチのアプローチ: Handler定義 14 ※動的ディスパッチ
© 2024 Finatext Holdings Ltd. 動的ディスパッチのアプローチ: 初期化 15
© 2024 Finatext Holdings Ltd. ケースバイケース Webアプリケーションの場合はIOの方がはるかにでかいので、生産性その他で決めるといいです 静的ディスパッチ vs 動的ディスパッチ
16
© 2024 Finatext Holdings Ltd. axum crateのStateのような仕組みを使う http crateのRequest構造体にはexstensionの仕組みがあるので、このexstensionに状態を毎回セットする tower::Serviceを作ると同じようなことが実現できる(はず)
ある程度の規模以上だと依存管理が煩雑になりそうなのでDependency Injdectionライブラリが有効そうだが少な い。DIパターンもデファクトがあるわけではなさそうなので今後の発展に期待(っぽい) Webアプリケーションでの交換可能性の実現 17
© 2024 Finatext Holdings Ltd. Webアプリケーションでの交換可能性の実現 18
© 2024 Finatext Holdings Ltd. モックを定義する・使う 19
© 2024 Finatext Holdings Ltd. • #[automock] ◦ 先の例のような典型的なケースではこのattribute macroで自動生成する
• mock! ◦ #[automock]マクロではダメなケースでこのproc macroで半手動(?)で生成する 名前に "Mock" prefixが付いた構造体が定義されるので、::newか::defaultで構造体を初期化する モック構造体の専用のメソッドを使ってモック対象のtraitのメソッド呼び出しのexpectationを設定する Expectation設定用のメソッド名は "expect_<original_method_name>" という規約 デストラクタで設定されたexpectationを検証する mockall crate 20
© 2024 Finatext Holdings Ltd. 例: モック定義 21
© 2024 Finatext Holdings Ltd. 例: モックを使う 22
© 2024 Finatext Holdings Ltd. 例: メソッドの引数の検証 23
© 2024 Finatext Holdings Ltd. • 構造体の実装のモックはできるが名前空間上でハック(?)が必要でやや微妙 ◦ 後述 •
Associated functions(static methods?)のモックはexpectationの設定がグローバルになるので、テスト の並列実行で同期ロジックが必要 ◦ なるべく避けたい • モジュール上の関数もモック可能だが名前空間上のハックが必要、かつexpectationの設定がグローバルにな る ◦ なるべく避けたい • モック対象のtraitのメソッドが参照を返す場合は制限あり • モック対象のtraitのメソッドの返り値がimpl Traitの場合は、mockall内部でBox<dyn Trait>に変換するの で制限あり • モック対象のtraitのメソッドの返り値がimpl Futureの場合は、返り値をpinningする必要あり ◦ 実際はasyncキーワードとasync-trait crateを使うことが多い(?) ◦ 後述 ドキュメントとexamplesがかなり丁寧でその他のケースも網羅してるので困った時はどうぞ mockallの注意点 24
© 2024 Finatext Holdings Ltd. async_traitマクロの手前にautomockマクロを置く。言い換えると、async_traitマクロで書き換えられた後の コードに対してautomockマクロでモック生成する async_traitマクロがその名前でimportされている必要あり。内部で使っているっぽい async-trait crateとの併用
25
© 2024 Finatext Holdings Ltd. 構造体の実装のモック 26
© 2024 Finatext Holdings Ltd. Associated Functionsの交換 27
© 2024 Finatext Holdings Ltd. 実用Rustアプリケーション開発 28 https://zenn.dev/taiki45/books/pragmatic-rust-application-development
None