Search code examples
unit-testingejbjmockit

JMockit can't find EJB, get NoSuchMethodException instead


Trying to mock a MessageDriven bean but have trouble getting the @EJB to be injected. The @Resource works "fine" (doesn't break it at least). If I comment out the @EJB line in MyMDB it works fine. Probably an easy thing I missed, but I can't find it...

Also I found that replacing @EJB with @Inject will make it work, but I want to know why it doesn't work with @EJB since we have a lot of code like that. Using JDK7 and JMockit v1.39

The error I get is:

java.lang.RuntimeException: java.lang.NoSuchMethodException: com.sun.proxy.$Proxy7.lookup()
Caused by: java.lang.NoSuchMethodException: com.sun.proxy.$Proxy7.lookup()
    at java.lang.Class.getMethod(Class.java:1678)

MyMDB.java:

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageListener;

@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "/queue/myqueue") })
public class MyMDB implements MessageListener {

    @Resource(mappedName = "java:/JmsBT")
    ConnectionFactory connectionFactory;

    @EJB
    ParConfigI parConfig;

    @Override
    public void onMessage(Message message) {
        System.out.println("onMessage called");
    }
}

MyMDBTest.java

import javax.jms.ConnectionFactory;
import javax.jms.Message;

import org.junit.Test;

import mockit.Injectable;
import mockit.Mocked;
import mockit.Tested;

public class MyMDBTest {
    @Tested
    MyMDB sut;

    @Injectable
    ConnectionFactory jmsbt;

    @Injectable
    ParConfigI parConfigI;

    @Mocked
    Message mockedMessage;

    @Test
    public void testSmall() {
        sut.onMessage(mockedMessage);
    }
}

ParConfigI.java

import javax.ejb.Local;

@Local
public interface ParConfigI {
    public void testmethod();
}

Solution

  • The problem is that JMockit attempts to read the lookup attribute on the @EJB annotation, but this attribute only exists in EJB 3.1+ (added in Java EE 6), not in EJB 3.0 (Java EE 5). Hence the NoSuchMethodException.

    JMockit 1.40 is fixing this, but Java EE 6 has been available since early 2010. So, upgrading from the ancient Java EE 5 would also solve the problem.