4

I am creating an EJB TimerService mock. Is there a way to manually trigger the call to a method with the @Timeout annotation?

user840930
  • 5,214
  • 21
  • 65
  • 94

2 Answers2

4

You can create new timer with preferred duration. When you need to call timeout call bellow code segment with duration. Then Framework should call timeout method within given duration from now.

context.getTimerService().createTimer(duration, "Hello World!");

Full code

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();
    }
}
Sanka
  • 1,294
  • 1
  • 11
  • 20
0

Now let's take into account that

The method is not public.

If you would like to test only the logic contained in method annotated with @Timeout, there are few solutions. I would recommend the last one, because it would also improve the overall design (see this answer).

  1. Make that method protected or package-private. This one is the simplest way to make that logic testable.
  2. Use reflection or PowerMock to invoke private method.

Here is a simple example, assuming that we want to invoke instance.timeOutHandlerMethod with Timer instance timer.

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

See doc page for more details.

  1. Extract logic to separate class and test it instead.

Here we extract logic from this.timeOutHandler to Delegate.execute:

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

to this:

private Delegate delegate;

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

With Delegate declared as:

class Delegate {

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

Now we can write a test for Delegate class.

Community
  • 1
  • 1
Mykhailo
  • 1,134
  • 2
  • 17
  • 25