我有一个我想要测试的EJB。我正在为JBoss EAP 6.4编写代码,但我想进行单元测试。 EJB(SendMessageTimer)继承自另一个类(ResettableTimer),该类具有注入@EJB的TimerService(理论上由EAP提供)(也尝试了@Resource)。 我发现了以下内容:Mocking EJB injection in tests这大概就是我想做的事情,但easygloss似乎已经死了 - 没有我能看到的下载,也没有在6年内更新过。我从这开始,它使用数据源做了类似的事情,所以看起来它应该是可能的:https://blogs.oracle.com/randystuph/entry/injecting_jndi_datasources_for_junit
public abstract class parentTimer {
@EJB
private static TimerService timerService;
Timer resettableTimer = null;
public void reset(){
//Nullpointer here!
resettableTimer = timerService.createTimer(timeout, getName());
}
@Timeout
public abstract void doTimerActions() throws Exception;
}
@EJB
public class SendTimer extends ResetableTimer {
public SendTimer() {}
@Override
@Timeout
public void doTimerActions() throws IOException, JMSException {
this.reset()
}
}
public class SendTimerTest {
private static InitialContext ic;
@BeforeClass
public static void setUpClass() throws Exception {
ic = createInitialContext();
makeAllSubcontexts(ic, "java:/javax/ejb");
TimerService mockTimerService = Mockito.mock(TimerService.class);
Timer mockTimer = Mockito.mock(Timer.class);
Mockito.when(mockTimerService.createTimer(Mockito.anyLong(), Mockito.any(String.class))).thenReturn(mockTimer);
ic.bind("java:/javax/ejb/TimerService", mockTimerService);
}
private static InitialContext createInitialContext() throws NamingException {
if (ic != null) {
return ic;
}
// Create initial context
Hashtable ht = new Hashtable();
ht.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
ht.put(InitialContext.URL_PKG_PREFIXES, "org.apache.naming");
ic = new InitialContext(ht);
return ic;
}
@Test
public void testDoAcTimerActions() {
TimerService service = (TimerService) ic.lookup("java:/javax/ejb/TimerService");
//This context is created successfully because the assert here passes
assertNotNull(service);
makeAllSubcontexts(ic, "java:/my/timers/package");
SendTimer sendTimer = new SendTimer();
sendTimer.setTimerService(service);
sendTimer.reset();
ic.bind("java:/my/timers/package/SendTimer", sendTimer);
SendTimer timer = (SendTimer) ic.lookup("java:/my/timers/package/SendTimer");
assertNotNull(timer);
timer.doTimerActions(); //Nullpointer from parentTimer
}
我在TimerService调用时得到一个nullpointer。我假设这是因为sendTimer是独立创建的,而不是由ic上下文初始化。另一件事可能是我在初始上下文的哈希表中使用了错误的属性。似乎有许多不同的可用,但我不确定这些差异。我想知道的是,是否可以从上下文(它可能会注入TimerService)创建sendTimer,而不是绑定一个现成的;这样做甚至有意义吗?我是否应该采用这种方法并使用测试框架,如果有的话,是否有任何建议? 提前感谢您提供的任何帮助。