如何触发@Timeout注释?

时间:2016-09-08 06:12:37

标签: java testing junit ejb

我正在创建一个EJB TimerService模拟。有没有办法手动触发带有@Timeout注释的方法的调用?

2 个答案:

答案 0 :(得分:3)

您可以使用首选持续时间创建新计时器。当你需要调用超时时,请调用带有持续时间的代码段。然后,Framework应该在给定的持续时间内调用timeout方法。

context。getTimerService()。createTimer(持续时间," Hello World!");

完整代码

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Timer;
import javax.ejb.Stateless;
import javax.ejb.Timeout;

@Stateless
public class TimerSessionBean implements TimerSessionBeanRemote {

    @Resource
    private SessionContext context;

    public void createTimer(long duration) {
    context.getTimerService().createTimer(duration, "Hello World!");
    }

    @Timeout
    public void timeOutHandler(Timer timer){
    System.out.println("timeoutHandler : " + timer.getInfo());        
    timer.cancel();
    }
}

答案 1 :(得分:0)

现在让我们考虑一下

  

该方法不公开。

如果您只想测试用@Timeout注释的方法中包含的逻辑,则解决方案很少。 我会推荐最后一个,因为它也会改善整体设计(见this answer)。

  1. 使该方法受保护或包私有。这是使逻辑可测试的最简单方法。
  2. 使用反射或PowerMock调用私有方法。
  3. 这是一个简单的例子,假设我们想要使用Timer实例instance.timeOutHandlerMethod调用timer

    Whitebox.invokeMethod(instance, "timeOutHandlerMethod", timer);
    

    有关详细信息,请参阅doc page

    1. 提取逻辑以分隔类并测试它。
    2. 我们在此处提取从this.timeOutHandlerDelegate.execute的逻辑:

      @Timeout
      private void timeOutHandler(Timer timer) {
          // some complicated logic
          timer.cancel();
      }
      

      到此:

      private Delegate delegate;
      
      @Timeout
      private void timeOutHandler(Timer timer) {
          delegate.execute(timer);
      }
      

      Delegate声明为:

      class Delegate {
      
          public void execute(Timer timer) {
              // some complicated logic
              timer.cancel();
          }
      }
      

      现在我们可以为Delegate类编写一个测试。