JUnit with Glassfish and JPA

2019-08-08 14:43发布

问题:

I've a web application that runs in Glassfish v3. It's realized with JSF v2 and JPA (so there's a persistence.xml where is declared a JTA-data-source).

If i try to test my repositories with JUnit, it fails the lookup and gives me this error:

javax.naming.NamingException: Lookup failed for 'java:comp/env/persistence/em' in SerialContext[myEnv=
java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory,
java.naming.factory.url.pkgs=com.sun.enterprise.naming, 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} 
[Root exception is javax.naming.NamingException: Invocation exception: Got null ComponentInvocation ]

It seems to ask for a transaction-type="RESOURCE_LOCAL" that i can't provide it, since it'd be in conflict with Glassfish's transaction-type="JTA".

So, what i'd like to ask is if it's possible to find a way to run JUnit without [strongly] change my webapp's configuration. Thanks, AN

回答1:

For real in-container tests you should have a look at Arquillian. It allows you to run your unit tests within the container.

You should have a look at the documentation at http://arquillian.org/guides/ and the showcases at GitHub at https://github.com/arquillian/arquillian-showcase/. There is also a JSF related showcase.

Regarding your configuration. I would strongly suggest to configure your project in such a way, that you can use a different configuration as in production.

If you need only a working JPA environment for your tests, then you should do the following:

  • Create a second JPA configuration with transaction-type="RESOURCE_LOCAL".
  • Add a setter for the entity manager to your beans.
  • Create the entity manager within your test setup as you would do it in an standalone Java application.
  • Inject the entity manager manually in the beans.
  • Try to use a mocking framework like Mockito to mock all other parts of the application which are not a part of the current test but required for the test.

The second approach depends on your architecture and the possibilities it offers to you. It allows you to write very fine-grained unit tests. The first approach is very usefull to test the real behaviour of your application in the container.