9

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)
Jean-François Côté
  • 4,200
  • 11
  • 52
  • 88

5 Answers5

4

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!

Jean-François Côté
  • 4,200
  • 11
  • 52
  • 88
1

I was able to fix the same issue by adding the following code snippet to the test Class.

@ObjectFactory
public IObjectFactory getObjectFactory() {
    return new PowerMockObjectFactory();
}
Dinithi
  • 518
  • 5
  • 17
0

I also got this error. In my case i missed @RunWith(PowerMockRunner.class) for my Class (i know it is silly mistake, but wasted few hours troubleshooting everything else :) ).

@RunWith(PowerMockRunner.class)
public class SimpleServiceUpgradeManagerTestNotUsed {
//Class content

}
Barani r
  • 2,119
  • 1
  • 25
  • 24
0

I also met this kind of exception, the reason is I didn't initialize the class to which the method I mocked belongs.

0

I encountered the same problem with codes below

catch (final HttpStatusCodeException e)

After I remove the final before HttpStatusCodeException, the Junit test works fine.

And I just use Mockito, no PowerMock

Vikki
  • 1,897
  • 1
  • 17
  • 24