1

I'm trying to test my Session Beans with JUnit, but I can't. I've tried a lot of method, but still get some exceptions. Here is what I need:

  • I have a few Stateless Session Beans I need to test. Each has the same @PersistenceContext and uses an EntityManager
  • With my test cases I need to test their methods. For instance: if I add an user with username X and then I try to add another one with the same username, I want to catch an Exception.

Can someone provide a simple and short generic test example? I've already read many, but I always get an error (I get NullPointerException for the EntityManager when I call a method like: sessionBean.method() (which does, for instance, entityManager.find(...)), or I am not able to initialize the Context, or other PersistenceException).

Simon
  • 5,070
  • 5
  • 33
  • 59
  • How are you writing your test cases? Do you use some integration framework like Arquillian or embedded EJB container like OpenEJB? – Piotr Nowicki Jan 22 '12 at 22:38
  • @PiotrNowicki I tried both (using mockito as framework). I don't know how to set them, what I need to import... Any method is fine, anyway. – Simon Jan 22 '12 at 22:54
  • I have a simple example : http://stackoverflow.com/questions/6469751/testing-an-ejb-with-junit/20635285#20635285 . Look at my answer. – Oliver Watkins Sep 30 '14 at 13:44

4 Answers4

4

You might be interested in one of the latest posts of Antonio Goncalves:

WYTIWYR : What You Test Is What You Run

It tells about testing EJB with EntityManager using:

  • Mockito,
  • Embedded EJB Container,
  • Arquillian.
Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
  • I'm reading it, but I see that he uses a mocked entity manager and inject it into its session bean (where there is `@DataSourceDefinition`). However, I use the `@PersistenceContext` with the `persistence.xml` descriptor. So, I don't know how to fit his example to my case. – Simon Jan 22 '12 at 23:28
  • He's mocking EntityManager only when neither the embedded EJB container nor the Arquillian are used. In any other cases he uses the actual EntityManager injected by the container. – Piotr Nowicki Jan 23 '12 at 21:33
1

I solved creating a Stateless Session Bean and injecting its Entity Manager to test classes. I post the code in case someone will need it:

@Stateless(name = "TestProxy")
@Remote({TestProxyRemote.class})
public class TestProxy implements TestProxyRemote {

    @PersistenceContext(unitName = "mph")
    private EntityManager em;

    @Override
    public void persist(Object o) {
        em.persist(o);
    }

    @Override
    public void clear() {
        em.clear();
    }

    @Override
    public void merge(Object o) {
        em.merge(o);
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object find(Class classe, String key) {
        return em.find(classe, key);
    }

    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object find(Class classe, long key) {
        return em.find(classe, key);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public List getEntityList(String query) {
        Query q = em.createQuery(query);
        return q.getResultList();
    }

}



public class MyTest {

    @BeforeClass
    public static void setUpBeforeClass() throws NamingException {
        Properties env = new Properties();
        env.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
        env.setProperty(Context.PROVIDER_URL, "localhost:1099");
        env.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
        jndiContext = new InitialContext(env);
        try {
            proxy = (TestProxyRemote) jndiContext.lookup("TestProxy/remote");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
}

Then I can use proxy.find() to get the entities I need, o proxy.getEntityList() to execute a query to retrieve all the instance of an Entity. Or I can add other methods if I want.

Simon
  • 5,070
  • 5
  • 33
  • 59
0

I'm using Needle for this. It works well with Mockito and EasyMock if you want to mock other objects.

First I write a persistencte.xml for tests (src/test/resources/META-INF) like this:

<persistence-unit name="rapPersistenceTest" transaction-type="RESOURCE_LOCAL">
    <properties>
     <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
     <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/test"/>
    ...
    </properties>
</persistence-unit>

In my Junit-Testclass I write:

public class DaoNeedleTest {

//here Needle will create persistenceContext for your testclass
public static DatabaseRule databaseRule = new DatabaseRule("rapPersistenceTest");

//here you can get the entityManager to manipulate data directly
private final EntityManager entityManager = databaseRule.getEntityManager();

@Rule
public NeedleRule needleRule = new NeedleRule(databaseRule);

//here you can instantiate your daoService
@ObjectUnderTest
DAOService daoService;

@Test
public void test() {
    //if your method needs a transaction here you can get it
    entityManager.getTransaction().begin();

    daoService.yourMethod();        

    entityManager.getTransaction().commit();
}

You also need a Needle-configuration File in src/test/resources, where you tell what kind of Mock-provider you are using. E.g. I'm using Mockito:

mock.provider=de.akquinet.jbosscc.needle.mock.MockitoProvider

That's it.

leopold
  • 98
  • 1
  • 7
0

Unitils provides a really cool support for JPA. Unitils can be used with JUnit or TestNG and in case you need a mocking framework, Unitils provides its own mocking module as well as support for EasyMock.

    @JpaEntityManagerFactory(persistenceUnit = "testPersistenceUnit")
    @DataSet(loadStrategy = RefreshLoadStrategy.class)
    public class TimeTrackerTest extends UnitilsTestNG {

        @TestedObject
        private TimeTrackerBean cut = new TimeTrackerBean();

        @InjectInto(target="cut",property="em")
        @PersistenceContext
        private EntityManager em;

        @Test
        @DataSet("TimeTrackerTest.testAddTimeSlot.xml")
        public void yourTest() {
            ...
        }
   }

@JpaEntityManagerFactory - Used to specify your persistence unit. It automatically picks up the persistence.xml from your project classpath. @DataSet - Just in case you need to load any test data you can use this. @TestedObject - Marks your Class Under Test @PersistenceContext - Automatically creates your EntityManager instance from the configurations made in the persistence.xml - PersistenceUnit. @InjectInto - Injects the em instance into the target (cut)

For more information refer this.

Hope this helps.

Bala
  • 1,193
  • 2
  • 12
  • 34