用 Mockito 模拟 return 一个 InvocationTargetException

Mock with Mockito return a InvocationTargetException

我正在写一些单元测试,我偶然发现了这个奇怪的 "bug",它阻止我 运行 进行我的单元测试。

当我 运行 "when(...).thenReturn(...)" 时,我收到一个 InvocationTargetException。然后奇怪的是,当我调试时,它进入真实对象并在 null 成员上崩溃。当我调试其他 "when" 时,它会进入一个名为 "Intercept" 的函数,该函数会阻止进入真实代码...我不明白这个对象有什么不同以及如何防止这种奇怪的行为.

这是我的单元测试:

@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
}

这是我的 setUp() 和我单位的成员部分 class 测试

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);
}

我不知道它是否相关,但 BrandSyncUpdater 和 StationSyncUpdater 都有一个名为 SyncUpdater 的父级,isDone() 函数位于该父级。

编辑

class

的层次结构

Updater 本身就是一个 class

BrandSyncUpdaterStationSyncUpdater 正在扩展 SyncUpdater

Updater isDone()签名及代码:

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

SyncUpdater isDone()签名及代码:

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

编辑 2

这是控制台中错误的堆栈跟踪。您会注意到此处的错误是 "NullPointerException",因为它尝试使用变量 currentStates。但是调试的时候mockito抛出的错误是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)

我刚刚通过尝试其他方法时出错发现了问题。

我的 SyncUpdater class 不是 public(它是包裹)。所以当尝试使用反射时,它卡住了并抛出这个奇怪的错误。

感谢评论里的人帮助!

我也遇到了这个错误。就我而言,我错过了 @RunWith(PowerMockRunner.class) 我的 Class (我知道这是一个愚蠢的错误,但浪费了几个小时来解决其他所有问题:))。

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

}

我也遇到过这种异常,原因是我没有初始化我mock的方法所属的class

我在使用下面的代码时遇到了同样的问题

catch (final HttpStatusCodeException e)

在我删除 HttpStatusCodeException 之前的 final 之后,Junit 测试工作正常。

而且我只使用 Mockito,没有使用 PowerMock