views:

655

answers:

2

I am writing some JNI code in C that I wish to test using cunit. In order to call the JNI functions, I need to create a valid JNIEnv struct.

Does anyone know if there is a mocking framework for such a purpose, or who can give me some pointers on how to create a mock JNIEnv struct myself?

A: 

Mocking JNI sounds like a world of pain to me. I think you are likely to be better off mocking the calls implemented in Java, and using Junit to test the functionality on the java side

David Sykes
The problem I have with your suggestion is that testing the code via Java is not unit testing as it them goes through the JNI. If it fails, it could be due to the Java code, the C/ Java datatype matching, the C coce, a bug in the JNI etc. cont...
David Arno
... So if I am to unit test JNI C code properly, I must mock the JNI and call the C functions from within C code.
David Arno
You're probably right, I've not done jni for a while, but it was the C/Java datatype matching that seems tricky to mock to me. Personally I'd think about wrapping the C/Java interface, and mocking that.
David Sykes
+1  A: 

jni.h contains the complete structure for JNIEnv_, including the "jump table" JNINativeInterface_. You could create your own JNINativeInterface_ (pointing to mock implementations) and instantiate a JNIEnv_ from it.

Edit in response to comments: (I didn't look at the other SO question you referenced)

#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;
}
Adam Mitz
Yep, that is what I've figured I need to do. To make life way more interesting though, Sun unhelpfully made the JNIEnv struct a constant so it overriding the function pointers within it becomes a seriously non-trivial task.
David Arno
If you are interested, http://stackoverflow.com/questions/203058/how-can-i-overcome-the-error-c2100-illegal-indirection-when-accessing-the-conte charts the solution to one of the problems of forcing pointer changes onto this const struct
David Arno