Я пишу код JNI на C, который хочу протестировать с помощью cunit. Чтобы вызывать функции JNI, мне нужно создать действительную структуру JNIEnv.
Кто-нибудь знает, есть ли для этой цели фиктивный фреймворк, или кто может дать мне несколько советов о том, как самому создать фиктивную структуру JNIEnv?





Издевательство над JNI звучит для меня как мир боли. Я думаю, вам, вероятно, будет лучше издеваться над вызовами, реализованными на Java, и использовать Junit для проверки функциональности на стороне java.
Проблема, с которой я столкнулся с вашим предложением, заключается в том, что тестирование кода через Java не является модульным тестированием, поскольку оно проходит через JNI. Если это не удается, это может быть связано с кодом Java, соответствием типа данных C / Java, кодом C, ошибкой в JNI и т. д., Продолжение ...
... Итак, если я должен правильно тестировать код JNI C, я должен издеваться над JNI и вызывать функции C из кода C.
Вы, наверное, правы, я не использовал jni какое-то время, но мне сложно высмеять сопоставление типов данных C / Java. Лично я бы подумал об упаковке интерфейса C / Java и издевательстве над ним.
jni.h содержит полную структуру для JNIEnv_, включая «таблицу переходов» JNINativeInterface_. Вы можете создать свой собственный JNINativeInterface_ (указывающий на фиктивные реализации) и создать экземпляр JNIEnv_ из него.
Изменить в ответ на комментарии: (я не смотрел на другой вопрос SO, на который вы ссылались)
#include "jni.h"
#include <iostream>
jint JNICALL MockGetVersion(JNIEnv *)
{
return 23;
}
JNINativeInterface_ jnini = {
0, 0, 0, 0, //4 reserved pointers
MockGetVersion
};
// class Foo { public static native void bar(); }
void Java_Foo_bar(JNIEnv* jni, jclass)
{
std::cout << jni->GetVersion() << std::endl;
}
int main()
{
JNIEnv_ myjni = {&jnini};
Java_Foo_bar(&myjni, 0);
return 0;
}
Ага, это то, что я решил, что мне нужно сделать. Тем не менее, чтобы сделать жизнь более интересной, Sun без особой пользы сделала структуру JNIEnv константой, так что переопределение указателей функций в ней стало серьезной нетривиальной задачей.
Если вам интересно, stackoverflow.com/questions/203058/… отображает решение одной из проблем принудительного изменения указателя на эту константную структуру.
Цитата: «jnimock реализован поверх gmock. Он предоставляет два класса C++ 'JNIEnvMock' и 'JavaVMMock' для раздельной имитации 'JNIEnv' и 'JavaVM'.
См. Отредактированную версию моего ответа, которая включает полную программу на C++ с фиктивной реализацией функции JNI.