Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock with Mockito return a InvocationTargetException

I'm writing some unit test and I stumble accross this strange "bug" which prevent me from running my unit test.

When I run the "when(...).thenReturn(...)", I receive a InvocationTargetException. Then strange things is that when I debug, it goes into the real object and crash on a null member. When I debug other "when", it goes in a function called "Intercept" which prevent to go in the real code... I don't understand what is different with this object and how to prevent this weird behavior.

Here is my unit test:

@Test
public void getSyncStatusShouldReturnValueFromDiskWhenNotRunning() throws IOException {
    //Arrange
    when(updater.isDone()).thenReturn(true);
    when(brandSyncUpdater.isDone()).thenReturn(true); //This is where it throw error
    when(stationSyncUpdater.isDone()).thenReturn(true);

    //Act
    //Assert
}

Here is my setUp() and member section of my unit class test

private Updater updater;
private BrandSyncUpdater brandSyncUpdater;
private StationSyncUpdater stationSyncUpdater;

@Before
public void setUp() {
    updater = mock(Updater.class);
    brandSyncUpdater = mock(BrandSyncUpdater.class);
    stationSyncUpdater = mock(StationSyncUpdater.class);
}

I don't know if it's related but the BrandSyncUpdater and StationSyncUpdater both have a parent called SyncUpdater where the isDone() function is located.

EDIT

Hierarchy of class

Updater is a class on its own

BrandSyncUpdater and StationSyncUpdater are extending SyncUpdater

Updater isDone() signature and code:

public boolean isDone() {
    return states.isEmpty();
}

SyncUpdater isDone() signature and code:

public boolean isDone() {
    return currentStates.isEmpty();
}

EDIT 2

Here is the stack traces of the error in the console. You'll notice that the error here is a "NullPointerException" because it try to use the variable currentStates. But when debugging, the error thrown by mockito is InvocationTargetException.

java.lang.NullPointerException
    at com.stingray360.clap.synchronizer.contentcontroller.queue.SyncUpdater.isDone(SyncUpdater.java:117)
    at com.stingray360.clap.synchronizer.contentcontroller.queue.BrandSyncUpdater.isDone(BrandSyncUpdater.java:15)
    at com.stingray360.clap.synchronizer.contentcontroller.SyncDispatcherTest.getSyncStatusShouldReturnValueFromDiskWhenNotRunning(SyncDispatcherTest.java:190)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
like image 808
Jean-François Côté Avatar asked Oct 19 '15 14:10

Jean-François Côté


People also ask

What does Mockito mock return?

Mockito mock() method When we didn't assign anything to mocks, they will return default values. All five methods perform the same function of mocking the objects. Following are the mock() methods with different parameters: mock() method with Class: It is used to create mock objects of a concrete class or an interface.

How do I resolve InvocationTargetException?

Since the InvocationTargetException is caused by another exception thrown by the invoked method, the underlying exception can be found using the getCause() method. Therefore, resolving the InvocationTargetException error equates to finding the actual exception and resolving it.

What is the difference between Wiremock and Mockito?

Wiremock provides a simulator for HTTP-based APIs while Mockito provides the mock implementation of the method/object.


1 Answers

I just found the problem by error trying something else.

My SyncUpdater class wasn't public (it was package). So when trying to use Reflection, it got stuck and throw this weird error.

Thanks for the help of people in the comments!

like image 139
Jean-François Côté Avatar answered Oct 11 '22 15:10

Jean-François Côté