JEE:使用模拟替换一个注入属性,用于容器外部的单元测试

时间:2016-05-11 16:21:11

标签: inheritance junit dependency-injection jboss6.x

我有一个我想要测试的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,而不是绑定一个现成的;这样做甚至有意义吗?我是否应该采用这种方法并使用测试框架,如果有的话,是否有任何建议? 提前感谢您提供的任何帮助。

0 个答案:

没有答案