gmockについて勉強してみた(7):自作テストダブルと比較してみる
どもです。
これまでgmockを使用したテストダブルの定義、および動作の指定方法を書いてきました。
これらの記事で、入門レベルの基本的な内容は書けたのかな、と考えています。
ところで、以下に挙げる投稿の中で、スタブ/テストダブルが持つべきと私が考えている機能を提案しています。
gmockが、これらの機能を提供できているのかを考えてみます。
- 単体テストの効率化を考える(2)-スタブの戻り値
- 単体テストの効率化を考える(3)-スタブの引数
- 単体テストの効率化を考える(4)-スタブの引数(ダブルポインタ)
- 単体テストの効率化を考える(5)-スタブの自動生成への入力
0. 作業環境:
作業環境です。
これまでと同様に、以下の環境で作業を行っています。
| 項目 | 内容 |
|---|---|
| CPU | Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz 3.20 GHz |
| RAM | 16.0 GB (15.9 GB 使用可能) |
| OS | Windows 10 Professional 22H2 (19045.5487) |
| IDE | Visual Studio Community 2022 (64bit), Version 17.14.8 |
| CMake | version 4.1.0 |
1. スタブ/テストダブルが持つべき機能のgmockでの実現可能性の確認
1.1. 呼び出し回数
まず、スタブ/テストダブルが持つべき機能として、呼び出し回数の保持です。
gmockでは、直接呼出し回数を保持する、ということはできません。
ここで、呼び出し回数は、スタブ/テストダブル化した関数が呼び出された回数を確認できるようにすることが、最大の目的です。
そのため重要なのは、呼び出し回数を保持していることではなく、呼び出し回数を確認できるか否かです。
gmockでは、Times()メソッドを使用することで、対象の関数が呼び出された回数が確認できます。
Times()メソッドを使用して呼び出し回数を確認するサンプルコードは以下の投稿にありますので、参考にしていただければと思います。
gMockについて勉強してみた(1):Windows上でgMockをビルドしてみた
1.2. 任意の戻り値の指定
次にスタブ/テストダブルが持つべき機能として、任意の戻り値の指定があります。
gmockでは、testing::Return()メソッドを使用することで、任意の戻り値を設定することができます。
また、スタブ/テストダブルが複数回呼び出される場合は、戻り値の設定方法は複数あります。
呼び出される度に同じ値を返す場合にはWillRepeatedly()メソッドを、異なる値を返す場合にはWillOnce()を使用します。
testing::Return()メソッドを使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(3):テストダブルの複数回呼び出し
なお、この投稿の中ではWillOnce()メソッドを使用しています。
WillRepeatedly()を使用したサンプルコードはありません。(スミマセン…。)
1.3. 引数の値の保持
次に、スタブ/テストダブルに渡された引数の値の保持です。
スタブ/テストダブルの引数の値の保持は、単に「引数で渡された値の保持」と、「ポインタ引数の実体の保持」の2つがあります。
それぞれの引数の値の保持について、gmockでの実現可能性を確認します。
1.3.1. 単純な引数の値の保持
まず、単に「引数で渡された値の保持」の方法です。
gmockによるスタブ/テストダブルの引数に渡された値の保持は、SaveArg()メソッドを使用します。
SaveArg()メソッドは、ポインタ引数を持ちます。
このポインタ引数に、スタブ/テストダブルに渡された値が格納され、引数の値が保持されます。
SaveArg()メソッドを使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(5):ポインタ引数で渡された値のコピー
SaveArg()メソッドは、スタブ/テストダブルの引数がポインタ/非ポインタであっても使用可能です。
1.3.2. ポインタ引数の実体の値の保持
次に、「ポインタ引数の実体の保持」の方法です。
gmockによるスタブ/テストダブルのポインタ引数の実体を保持するためには、Invoke()メソッドを使用します。
ただし、Invoke()メソッド自体が、ポインタ引数の実体を保持してくれるわけではありません。
Invoke()メソッドでは、スタブ/テストダブルが呼び出された際の動作を指定することができます。
この動作に、引数の値を保持する処理を指定することで、ポインタ引数の実体を保持することができます。
Invoke()メソッドを使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(5):ポインタ引数で渡された値のコピー
1.4. ポインタ引数への値の格納
次に、スタブ/テストダブルの引数への値の格納です。
このパターンは、ポインタ型かつ出力となる引数を持つメソッドのスタブ/テストダブルが持つべき機能です。
この機能の動作は、ポインタがシングルポインタの場合とダブルポインタの場合で、それぞれ異なっています。
それぞれの場合について、gmockでの実現可能性を確認してみます。
1.4.1. シングルポインタの場合
まず、出力となるポインタがシングルポインタの場合の動作です。
この場合、テストダブルは、指定されたアドレスに任意の値を格納する、という動作をする必要があります。
ここで、指定されたアドレスの実体が配列か否かによって、使用するgmockのメソッドが異なります。
1.4.1.1. アドレスの実体が配列ではない場合
アドレスの実体が配列ではない場合は、SetArgPointee()メソッドを使用します。
SetArgPointee()メソッドの第1引数に指定した値が、指定されたアドレスの実体にセットされます。
SetArgPointee()を使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(2):ポインタ引数を持つメソッドのモック
gmockについて勉強してみた(3):テストダブルの複数回呼び出し
1.4.1.2. アドレスの実体が配列の場合
アドレスの実体が配列であった場合には、SetArrayArgument()を使用します。
SetArrayArgument()メソッドの第1引数に、アドレスの実体に格納したい値を保持している領域の先頭アドレスを指定します。
第2引数には、アドレスの実体に格納したい値の末尾のアドレスを指定します。
(「アドレスの実体に格納したい値を保持している領域の末尾」ではないことに注意が必要。)
SetArrayArgument()を使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(4):ポインタの実体が配列であった場合
1.4.2. ダブルポインタの場合
次に、出力となるポインタがダブルポインタの場合の動作です。
この場合、テストダブルは、ダブルポインタの実体に、任意の領域のアドレスを格納する、という動作をする必要があります。
そのために使用するgmockもメソッドは、SetArgPointee()です。
はい。
引数がシングルポインタかつ出力であった場合と、同じメソッドを使用します。
「ポインタ引数の実体に、任意の値をセットする」という意味では、シングルポインタでもダブルポインタでも同じ動作になります。
引数がダブルポインタであった場合に、SetArgPointee()を使用したサンプルコードは、以下の投稿にあります。
gmockについて勉強してみた(6):ダブルポインタ引数を持つメソッドのモック
2. まとめ
今回は、以前の投稿で提案したスタブ/テストダブルが持つべきと考える機能について、gmockが提供できているか確認しました。
結果として、gmockでも同等の機能を提供、実現できると確認できました。
以前の投稿で提案した内容では、スタブ/テストダブルを全て手動で実装する必要がありました。
しかしgmockでは、提供されているメソッドを使用することで、これらの実装をすることなく同等の内容を実現できることが分かりました。
この記事の内容が、誰かの助けになれば幸いです。
ではっ!



ディスカッション
コメント一覧
まだ、コメントがありません