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
自動テストでモックするって、なにそれ?おいしいの?/what_is_mocking
Search
marchin
April 14, 2022
Programming
1
1.2k
自動テストでモックするって、なにそれ?おいしいの?/what_is_mocking
marchin
April 14, 2022
Tweet
Share
More Decks by marchin
See All by marchin
ブラックフライデーで購入したPixel9で、Gemini Nanoを動かしてみた
marchin1989
1
750
Amazon Athenaで気軽に始める データ分析/athena-data-analytics
marchin1989
0
580
WebAPI開発のためのOpenAPI入門/entry-open-api
marchin1989
1
1.3k
AWS Glueではじめるデータレイク
marchin1989
0
660
やさしく入門するOAuth2.0/easy-entry-oauth
marchin1989
8
2.3k
1時間半で克服するJavaScriptの非同期処理/async_javascript_kokufuku
marchin1989
2
1.5k
たぶんもう怖くないGit/maybe-not-afraid-of-git-anymore
marchin1989
2
2.6k
モバイルアプリで機械学習入門/introduction-to-machine-learning-in-mobile-app
marchin1989
0
480
Other Decks in Programming
See All in Programming
関数の挙動書き換える
takatofukui
4
640
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
5
950
Bakuraku E2E Scenario Test System Architecture #bakuraku_qa_study
teyamagu
PRO
0
760
What’s Fair is FAIR: A Decentralised Future for WordPress Distribution
rmccue
0
180
GraalVM Native Image トラブルシューティング機能の最新状況(2025年版)
ntt_dsol_java
0
140
複数チーム並行開発下でのコード移行アプローチ ~手動 Codemod から「生成AI 活用」への進化
andpad
0
170
開発生産性が組織文化になるまでの軌跡
tonegawa07
0
170
Honoを技術選定したAI要件定義プラットフォームAcsimでの意思決定
codenote
0
240
AI駆動開発ライフサイクル(AI-DLC)のホワイトペーパーを解説
swxhariu5
0
1k
CSC509 Lecture 11
javiergs
PRO
0
310
モデル駆動設計をやってみよう Modeling Forum2025ワークショップ/Let’s Try Model-Driven Design
haru860
0
160
高単価案件で働くための心構え
nullnull
0
140
Featured
See All Featured
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
192
56k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
2.9k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Building a Scalable Design System with Sketch
lauravandoore
463
33k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
Six Lessons from altMBA
skipperchong
29
4.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Rails Girls Zürich Keynote
gr2m
95
14k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Mobile First: as difficult as doing things right
swwweet
225
10k
Transcript
自動テストでモックするって、 なにそれ?おいしいの? 〜依存コンポーネントをコントロールして、上手なテストコードを実装しよう〜
自己紹介 - 名前: 阿部 真之 - 仕事: 株式会社ゆめみ でAndroidエンジニアしてます -
最近はサーバサイド Kotlinの仕事も始めました - 趣味 - コーヒー、ビール、アニメ、ゲーム、読書、 etc… - Twitter: @marchin_1989
アジェンダ - ユニットテストの例 - テストダブルとは - テストダブルの分類(サンプルコードで解説) - その他注意点など
ユニットテスト書いてますか?
ユニットテスト コンピュータプログラミングにおいて単体テスト(たんたいテスト)あるいはユニットテスト (英語: Unit test)とは、ソースコードの個々のユニット、すなわち、1つ以上のコンピュー タプログラムモジュールが使用に適しているかどうかを決定するために、関連する制御 データ、使用手順、操作手順とともにテストする手法である。ユニットとはアプリケーショ ンのテスト可能な最小の部品単位である、と直観的にとらえることができる。 (Wikipedia) ここでは、自動テストの文脈でユニットテストをみていきます。
ユニットテストしてみよう
- テストダブルってなに? - モック、スパイ、ダミーとか聞いたことあるけど。。 テストダブル?
テストダブルとは? - テストダブルとは、テスト実行時に、テスト対象が依存している外部のコンポーネン トと置き換わるもの。 @Test fun `テストコード`() { assertEquals(期待値, テスト対象())
} fun テスト対象(): Int { … 依存コンポーネントのメソッド() … }
本番 テスト
なぜテストダブルに置き換えたいのか テスト対象が外部のコンポーネントに依存しており、テスト環境で利用できなかったり、 利用しづらかったりなど、制約(コスト、処理時間)があるとき。 - テストに必要な結果をコントロールできない(実行するたびに値が変わる) - 実行に時間がかかる - 用意するのにお金がかかる
テストダブルにはどんなものがあるの? - xUnit Test Patternsによる定義、分類が有名 - xUnit Test Patternsとは、テスト自動化フレームワークの xUnit(JUnitやNUnitなど)を使用して自動
テストを作成するためのパターン (本)。 - 分類 - ダミー(Dummy Object) - スタブ(Test Stub) - スパイ(Test Spy) - モック(Mock Object) - フェイク(Fake Object) 出典: xUnit Test Patterns Test Double http://xunitpatterns.com/Test%20Double.html
テストダブルの分類を知っておく利点 - それぞれの役割を理解しておくと、テストダブルに対して何をやらせばいいのか明 確になる。適切なテストダブルを選べる。 - モックライブラリのAPIが何を提供しているのか理解しやすくなる。 - ただし、xUnit Test Patternsのテストダブルの分類と言葉が一致しなかったりするので要注意。
- (逆説的だが)自分が作成したいテストケースが明確になる。
以降の説明の流れ - テストダブルとその分類 - それぞれ、実際にどうやって置き換えるのか、サンプルコードで紹介(Kotlin)
テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テストダブルの分類 主に「外部への入出力」でテ ストダブルを分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テスト対象への入力 のコントロール テストダブルの分類
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する テスト対象からの出 力の記録 テストダブルの分類
ダミー
ダミー(Dummy Object) - テストメソッド内で、なにもしない。 - テスト対象に影響を与えないが、コンパイルなどの都合上、用意しないといけないも の。
ダミーのサンプルコード
スタブ
スタブ(Test Stub) - 入力を操作し、任意の値をテスト対象に与える。 - 入力値をテストコード上で、事前設定し、テストを実行。
スタブのサンプルコード
スパイ
スパイ(Test Spy) - テスト対象からの出力を記録。 - テストコード上でその記録した出力を検証する。 - ただし、入力を操作することもある。つまりスタブのように振る舞うこともある。
スパイのサンプルコード
モック
モック(Mock Object) - テスト対象からの出力を記録 - テスト対象内の外部コンポーネントへの出力の期待結果(expected)をセットする - テスト対象を実行しながら、テスト対象から外部コンポーネントへの出力を取得し、 モック内部で期待結果と出力結果を比較して、成功か失敗かを判定する -
テストコードからは、モックから検証の成功 or 失敗を受け取る - スタブの機能を持つことがある
スパイとモックの違い - 両方とも、外部コンポーネントへの出力を検証するためのテストダブル。 - ただし、モックは、テスト対象のメソッドを呼び出す前に、事前に期待結果をセットす る。その後、モック内で出力の結果を評価する。 - スパイは、外部コンポーネントへの出力を保持するだけ。外部コンポーネントへの 出力結果の評価は後からテストコード上で行う。
フェイク
フェイク(Fake Object) - テスト実行中、本物ではないが、本物と同じように動作する。 - 本物がテスト環境で使えないとか、返答が遅いなどの理由で利用する。 - テストの実行環境のマシンで起動しておいて、接続先を変更するなどで置き換える - 例
- RDBに対し、同じ機能を持ったオンメモリのデータベース。 - AWSの機能をエミュレートした LocalStack。DynamoDB Local。
以上、テストダブルの分類でした
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。 - モックライブラリで実装されている名前と、xUnit
Test Patternsのテストダブルの分 類は必ずしも一致しない
その他 - ややこしいが、テストダブルの生成を単に「モックする」ということがある。 - 「スタブの入力値自体をテストする」のような意味のないユニットテストを書いてしま うことがあるので注意。 - テストダブルは、まだ実装していないコードの代替となる。 - モックライブラリで実装されている名前と、xUnit
Test Patternsのテストダブルの分 類は必ずしも一致しない - モックライブラリによっては挙動が異なるので、利用するときはよく挙動を理解して おくこと - rspec-mocks(Ruby)のスパイは、置き換えられた本物の依存コンポーネントの処理は実行されな い - MockK(Kotlin)やJest(JavaScript)のスパイは、デフォルトだと、置き換えられた依存コンポーネン トの処理も実行される。プロキシのような挙動。
外部からの入力 外部への出力 主な役割 ダミー × × 何もしない。インスタンスが必要になる場合に利用。 スタブ ◯ ×
外部コンポーネントからの入力を操作する スパイ ◯ ◎ 外部コンポーネントへの出力を記録する 出力結果をテストコードから取り出して評価 モック ◯ ◎ 外部コンポーネントへの出力を記録する 出力の期待結果を持ち、モック内で評価 フェイク ◯ ◯ 本物ではないが、本物と同じように動作する まとめ テスト対象への入力 のコントロール テスト対象からの出 力の記録