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)
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.
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.
Wiremock provides a simulator for HTTP-based APIs while Mockito provides the mock implementation of the method/object.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With