Search code examples
junitejbcdiopenjpaapache-tomee

CDI injection and JUnit


I am trying to add JUnit tests to a Tomee web-application that uses CDI and JPA. Leaving out the different hurdles of the last two weeks (including very intensive research on stackoverflow as well as other sources), my problem appears to be quite concrete:

Running the unit test gives this error message:

org.apache.openejb.Injector$NoInjectionMetaDataException: 
org.demo.service.GenericServiceTest : Annotate the class with @javax.annotation.ManagedBean so it can be discovered in the application scanning process
    at org.apache.openejb.Injector.inject(Injector.java:54)
    at org.apache.openejb.OpenEjbContainer$GlobalContext.bind(OpenEjbContainer.java:656)
...

This I don't understand, for I have annotated the class just as required. Any idea what I can do to resolve this?

(Or does the error refer to the injected class - GenericService? I cannot annotate this @ManagedBean, for it is already @Stateless).

Here are some details of my project:

gradle dependencies:

dependencies {

    compile 'org.apache.commons:commons-lang3:3.3.2'
    compile "com.googlecode.json-simple:json-simple:1.1.1"
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.8.6'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.6'
    compile 'log4j:log4j:1.2.16'
    testCompile "org.apache.openejb:tomee-embedded:1.7.3"
    compile "javax:javaee-api:7.0"
    compile 'mysql:mysql-connector-java:5.1.16'
}

(I have put the testCompile inbetween, because there is a ticket stating the importance of the order: EJB testing with TomEE embedded EJBContainer api: java.lang.ClassFormatError exception)

My Test class is this:

package org.demo.service;

import java.io.File;
import java.util.Properties;

import javax.annotation.ManagedBean;
import javax.ejb.embeddable.EJBContainer;
import javax.inject.Inject;
import javax.naming.NamingException;

import org.apache.openejb.OpenEjbContainer;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

@ManagedBean
public class GenericServiceTest {
    private static EJBContainer ejbContainer;

    @Inject
    private GenericService service;

    @Test
    public void test() throws NamingException {
        System.out.println("service: " + service);
    }

    @BeforeClass
    public static void start() {
        Properties p = new Properties();
        try {
            p.put(EJBContainer.MODULES, new File("bin"));
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        p.put(OpenEjbContainer.Provider.OPENEJB_ADDITIONNAL_CALLERS_KEY, GenericService.class.getName());
        ejbContainer = javax.ejb.embeddable.EJBContainer.createEJBContainer(p);
    }

    @Before
    public void inject() throws NamingException {
        ejbContainer.getContext().bind("inject", this);
    }

    @AfterClass
    public static void shutdownContainer() {
        if (ejbContainer != null) {
            ejbContainer.close();
        }
    }
}

Maybe I'm running totally in the wrong direction here - Please let me know if I should choose a different approach - All I want is to add unit tests to my web application (preferably without introducing Weld/JBoss or other implementations as alternatives to the implementations I already use in the application itself).

Thank you very much in advance!


Solution

  • I would recommand you to read http://tomee.apache.org/developer/testing/index.html , there are some examples

    Regarding your test it uses openejb embedded and not tomee embedded and deploys bin/ as an application. the hack bind("inject") only works with classpath deployment (no module).