Envelope/Quill TestingJNI

- Last edited November 20, 2002
Ok, I am outside of my VisualAge comfort zone. As I find ways of testing JNI, I will endevour to put them here. PaulSimmons
Meanwhile, anyone had any experience in this field? My initial problem is one of environment (but not an uncommon one). The C++ libraries are unix and VisualAge isn't (well at least not the right flavour).

You mean the C++ libraries are Sun Sparcworks on Solaris I guess? C++ has no binary linkage standard, so it matters. For that matter, JNI knows nothing of C++ calling conventions, only C (with some C++ syntactic sugar thrown in). So how are you linking the two? -- PhilipCraig?

I am not. At the moment, my sugary C is on Solaris and uses 3rd party libs that I cannot recompile. As java is portable, I can run junit tests on Solaris (its just that VA isn't there). -- PaulSimmons

Apart from a slower turnaround when coding, what are the difficulties with TestingJNI? --SteveFreeman


Worked Example I welcome comments on this! Lets take an example class, Widget, which has a native method
 doCalculate( double a, double b) answering a double.  
How can we test this method? Two ways come to mind at the moment:

(1) I can consider the native C++ implementation as integral to Widget. So I write junit TestCase implementations such as:

 public void testCalculationAccuracy()
 {
 Widget aTestWidget = new Widget();
 assert( 6.0 == aTestWidget.doCalculate( 1.0, 5.0) );
 }
I see this means that my test suite is now dependant on platform and C++ library compilations, which slows me down (running every 15 mins might be an issue) as noted by Steve above.

(2) I can mock-up the C++ implementation with java, and separate the test suite into two; a cppunit and junit. This separates dependancies between platform/language. But to do this I have to create AbstractWidget? and its derivations Widget and MockWidget?.

I need this because I cannot have native methods on an interface or abstract class, only on the derivative Widget.


TestingForMemoryLeaksInJNI How can I test for resilience issues such as memory leakage? Call Runtime.freeMemory() before and after?

The C++ (and C) runtime libraries use a completely separate heap to the JVM most likely. So that won't tell you. -- PhilipCraig? Are you sure, the JNIProgrammers guide book from Sun implies something different?


The standard mocking techniques can help you with this.
  1. Make sure you make your JNI class as small and simple as possible. In the above example move doCalculate to a separate class WidgetJni?, which has an interface WidgetCalc?
  2. Make a MockWidgetJni class that conforms to WidgetCalc? and write tests where you set expected values in your mock implementation. This means your Widget class needs to be instantiated or configured with a WidgetCalc? so that you can do this
  3. When all the tests run you are ready to plug in your real Jni implementation - if this object is as simple as possible, you might be able to get away with visual inspection of the code, or at least write a functional test executable that loads the dll and displays the results for manual test. Or take that small bit of code and use CPPUnit to test it in isolation - however you should be able to isolate it enought to view it as a functional test. -- TimM

Thanks Tim, I understand your standard mocking techniques above as the same as point (2) above that. Let me know and I will rework this wiki page to be clearer.

Re your last suggestion; making the C code small is a general rule for JNI. However, the example is unrealistic here as the C code is communicating with a 3rd party library. This means there are some complex test cases required in junit (to exercise my java logic) depending on the various states in the underlying lib. My MockWidgetJNI? will help me here, I hope.

Any other comments, or alternative ideas folks?

OliBye suggests using Junc++ion from CodeMesh?


- Last edited November 20, 2002

https://casino-brain.com/