質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.32%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

1回答

180閲覧

CppUMockでポインタが指す構造体のメンバ関数をモックしたい

neoneko

総合スコア24

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2025/03/11 12:16

編集2025/03/11 17:08

実現したいこと

・ポインタが指す構造体のメンバ関数をモックしたい
(表現が間違っていたらすみません)

前提

仕事の関係で, 既存のC言語のコードに単体テストのためのテストコードを作成する必要があります。
しかし、C言語の知識に疎いため、モックのやり方が分からず苦戦している所です。
CppuMockの利用方法に関しては以下の2サイトを参照しています。
https://www.kumikomist.com/tool/cppumock/
https://cpputest.github.io/mocking_manual.html

該当のソースコード

ソースコード(抜粋)

C言語

1 JavaVM *vm = NULL; 2 jsize ct; 3 jint ret1 = JNI_GetCreatedJavaVMs( &vm, 1, &ct ); 4 JNIEnv *env = NULL; 5 printf("JavaVM pointer (vm): %p\n", (void*)vm); 6 // ↓のモックを実現したい 7 jint ret2 = ( *vm )->GetEnv( vm, ( void** )&env, JNI_VERSION_21 ); 8 printf("getJNIEnv Return value (ret): %d\n", ret2); // ret の値を表示 9 printf("getJNIEnv JavaVM pointer (env): %p\n", (void*)env); 10 if ( ret2 == 0) { 11 return env; 12 }

試したこと

テストコードとしてCpputestを利用して以下のようなコードを記載しています。
どうにかGetEnvを呼び出せないか試した結果となります。

C言語

1#include <CppUTest/TestHarness.h> 2#include <CppUTestExt/MockSupport_c.h> 3 4extern "C" { 5 // ソースのヘッダー 6 #include "xxx.h" 7} 8 9extern "C" { 10 // モックする構造体 11 typedef struct { 12 jint (*GetEnv)(JavaVM *, void **, jint); 13 } MockJavaVM; 14 15 // GetEnvのモック関数 16 jint MockGetEnv(JavaVM *vm, void **env, jint version) { 17 mock_c()->actualCall("GetEnv") 18 ->withOutputParameter("env", env); 19 return mock_c() -> intReturnValue(); 20 } 21 22 // JNI_GetCreatedJavaVMsのモック関数 23 jint JNI_GetCreatedJavaVMs(JavaVM **vm, jsize size, jsize *nvm) { 24 MockJavaVM mockedVM; 25 mockedVM.GetEnv = MockGetEnv; // モック関数を設定 26 *vm = (JavaVM*)&mockedVM; // vm が指す先に MockJavaVM のアドレスを設定 27 mock_c()->actualCall("JNI_GetCreatedJavaVMs") 28 ->withOutputParameter("vm", vm); 29 return mock_c()-> intReturnValue(); 30 } 31} 32 33TEST_GROUP(XXXgetJNIEnvTest) { 34 void teardown() { 35 mock_c()->clear(); 36 } 37}; 38 39TEST(MSCLibgetJNIEnvTest, Test_getEnv_Success) { 40 JNIEnv *result; 41 JavaVM *mockVM; 42 JNIEnv *env; 43 int attach = 0; 44 45 // getVM()で利用する関数のmock 46 mock_c()->expectOneCall("JNI_GetCreatedJavaVMs") 47 ->withOutputParameterReturning("vm", &mockVM, sizeof(mockVM)) 48 ->andReturnIntValue(0); 49 50 // テスト実行 51 result = getJNIEnv(&attach); 52 53 // 結果の検証 54 CHECK(result == env); 55}

ちなみに以下のようにGetEnvをテストコードから直接呼ぶようにもしてみたのですが、呼び出しができませんでした。

C言語

1 // GetEnvのモック関数 2 jint GetEnv(JavaVM *vm, void **env, jint version) { 3 mock_c()->actualCall("GetEnv") 4 ->withOutputParameter("env", env); 5 return mock_c() -> intReturnValue(); 6 }

cpputestの実行結果

以下のエラーが発生。

JavaVM pointer (vm): 0x455f60 Return value (ret2): 1      ← retの値が制御できていない (実施方法が不明) JavaVM pointer (env): (nil) ← envの値が設定できていない xxx.cpp:187: error: Failure in TEST(MSCLibgetJNIEnvTest, Test_getEnv_Success) CHECK(result == env) failed

期待する結果としては以下2点です。
・ret2の結果をモックしたい
・envの値を設定したい

表現の方法が誤りの可能性がもあれば、申し訳ございません。
何か良い方法をご存じの方がいらっしゃればご教示いただきたいです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

すみませんが、簡単に再現環境が作れそうになかったので、動作確認はできていません。

モックにしたいのはGetEnvなわけですから、それのモック関数であるMockGetEnvへのモック定義をしないといけないのではないでしょうか?

具体的には以下の部分はJNI_GetCreatedJavaVMsへのモック定義になっているので、MockGetEnvへのモック定義もしないといけないと思います。

c

1mock_c()->expectOneCall("JNI_GetCreatedJavaVMs") 2 ->withOutputParameterReturning("vm", &mockVM, sizeof(mockVM)) 3 ->andReturnIntValue(0);

投稿2025/03/11 17:17

toge_

総合スコア306

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.32%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問