【发布时间】:2018-02-07 12:01:23
【问题描述】:
我已经阅读了这篇文章:Is there a way in JMockit to call the original method from a mocked method?
但推荐的解决方案会引发 NPE。这是我的来源
static Map<String, Boolean> detectDeadlocks(int timeInSeconds) {
final Map<String, Boolean> deadlockMap = new LinkedHashMap<>();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// I want to check if the method is run.
**deadlockMap.put("deadlock", isDeadlockAfterPeriod());**
}
}, timeInSeconds * 1000);
return deadlockMap;
}
我希望能够在我的单元测试中调用isDeadlockAfterPeriod。这是我在单元测试中模拟的静态方法。
我的单元测试代码
@Test
public void testDetectDeadlocks() throws Exception {
new Expectations(){
{
// Called from inside the TimerTask.
ClassUnderTest.isDeadlockAfterPeriod();
result = false;
}
};
TimerMockUp tmu = new TimerMockUp();
Deadlocks.detectDeadlocks(0);
Assert.assertEquals(1, tmu.scheduleCount);
}
class TimerMockUp extends MockUp<Timer> {
int scheduleCount = 0;
@Mock
public void $init() {}
@Mock
public void schedule(Invocation invocation, TimerTask task, long delay) {
scheduleCount ++;
invocation.proceed(); // Trying to call the real method, but this throws a NPE.
}
}
在 Eclipse 中使用 JUnit 可以看到错误堆栈跟踪。
java.lang.NullPointerException
at com.myproject.test.DeadlocksTest$TimerMockUp.schedule(DeadlocksTest.java:78)
at com.myproject.test.Deadlocks.detectDeadlocks(Deadlocks.java:41)
at com.myproject.test.DeadlocksTest.testDetectDeadlocks(DeadlocksTest.java:86)
【问题讨论】:
-
对于静态资源,可以使用PowerMock API来模拟。
-
您能否添加 NPE 的堆栈跟踪以了解
null的实际含义。 -
@PrathibhaChiranthana 我正在使用 jMockit 库。
-
@dpr 更新帖子。
-
其实我觉得你方法的设计对测试不太友好。我将创建一个为
TimerTask创建Runnable的方法。这样您就可以轻松地对Runnable进行单元测试,而无需过多地模拟。
标签: java unit-testing jmockit