Search code examples
javaunit-testingjava-native-interfaceinversion-of-control

How to unit test a library that uses JNI?


Unit testing best practices call for the use of inversion of control to ensure that unit tests run independently of each other even if they depend on singleton instances (each test gets their own "singleton").

What is the recommendation for testing a library that uses JNI to manipulate a native resource that only exists once per Process (e.g. the terminal)?

I'm not asking about testing the actual JNI code but rather the Java code that depends on the native code as a side-effect.


Solution

  • Its the same as usual.

    You create a mock of the library class your code under test (cut) uses and verify the communication between your cut and that mock.

    class JniUsageTest{
    
      @Rule 
      public MockitoRule mockitoRule = MockitoJUnit.rule(); 
    
      @Mock
      private JniInterfaceClass jni;
    
      @Test
      public void testJniCommunication_SomethingToWrite_PassedToInterface(){
        // arrange
        doReturn("the Answer from JNI").when(jni).calledByCut(any(Object.class));
        YorClassUnderTest cut = new YorClassUnderTest(jni);
    
        // act
        String resultContainingJniReturn =  cut.doSomethingExpectedToWtiteToJni();
    
        // assert
        verify(jni,times(10)).calledByCut(any(Object.class));
        assertThat(resultContainingJniReturn, containsString("the Answer from JNI"));
      }
    
    }