Hot questions for Using Enterprise JavaBeans in junit

Question:

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


Answer:

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();
    }
}

Question:

I have a main EJB that injects a DAO EJB:

@Stateless
@LocalBean
public class MainEjb {

    @Inject
    private DaoEjb dao;

    public MyClass someMethod(int i) {
         return dao.read(i);
    }

}


@Stateless
@LocalBean
public class DaoEjb {

     public MyClass read(int i){
          // get MyClass object using jdbc
          return object;
     }
}

Now, I want to test MainEjb.someMethod() using jUnit + Mockito, injecting in the test the real MainEjb, and mocking the DaoEjb.read() method to return aMyClass` object (instead of making a jdbc call):

@RunWith(MockitoJUnitRunner.class)
public class UserBeanUnitTest {

    @InjectMocks
    private MainEjb bean;

    DaoEjb dao = mock(DaoEjb.class);


    @Test
    public void testBean() {

        MyClass object = new MyClass();
        // set object fields

        assertThat(bean.someMethod(1)).isEqualTo(object);
    }

}

The problem is that I don't know how to connect the bean and dao beans, so this doesn't work. I know I can do this with Arquillian, but I'm trying to avoid instantiating a container. Can this be done with Mockito?


Answer:

Your example worked for me. I just added a rule for dao:

@Test
public void testBean() {

    MyClass object = new MyClass();
    // set object fields
    Mockito.when(dao.read(Matchers.eq(1))).thenReturn(object);

    assertThat(bean.someMethod(1)).isEqualTo(object);
}