Unit Tests von EJBs (mit JPA) mittels Embedded Glassfish v3 in NetBeans 6.8 und Maven
Unit Tests sind in Java EE Anwendungen nicht so einfach zu realisieren, da die EJBs im EJB Container ablaufen. Daher gibt es seit 3.1 so genannte Embedded EJB Container. Darüber gibt es auch wieder einige tolle Blog Einträge, doch leider hat mich keiner der vorhanden direkt zum Erfolg geführt, deshalb hier mal meine Anleitung.
Wie der Titel schon sagt verwende ich NetBeans 6.8 mit Glassfish v3 und Maven für meine Java EE 6 Anwendung. Wie es sich gehört wird fleißig Einsatz von JPA gemacht. Hier wird mal vorausgesetzt, dass die Anwendung schon brav Kontakt zur Datenbank aufgenommen hat, in meinem Fall MySQL, sprich alle JDBC Pools und Connections wurden erfolgreich angelegt. Somit können wir später direkt die Konfiguration der Domains des richtigen Glassfish Application Servers in unserem Embedded Container verwenden um mittels JPA auf die Datenbank zu zu greifen. Wer lieber zum Testen eine seperate Datenbank nehmen möchte kann hier nachlesen wie er da vorgehen muss.
Als erstes muss die embedded Version des Glassfishes in Maven eingebunden werden. Hier ergab sich bereits mein erstes Problem, da sich die Repositories und der notwendige Dependency Eintrag nicht so einfach im Internet finden lassen. Deshalb hier die Abhängigkeit:
<dependency> <groupId>org.glassfish.extras</groupId> <artifactId>glassfish-embedded-all</artifactId> <version>3.0</version> <scope>test</scope> </dependency>
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0</version> <scope>provided</scope> </dependency>
Der untere Eintrag wird für den Container zwar nicht benötigt, wird hier aber dennoch erwähnt, da es wichtig ist, das der embedded Glassfish Eintrag vor diesem in der pom.xml erscheint, da es sonst zu Fehlermeldungen beim Testen und Deployen kommen kann.
Der zugehörige Repository Eintrag lautet wie folgt:
<repository> <id>embedded-glassfish</id> <name>Embedded Glassfish Maven Repository</name> <url>http://download.java.net/maven/glassfish</url> </repository>
Nun sollten diese Abhängigkeiten erstmal durch ein Build besorgt werden um zu sehen ob hier alles geklappt hat. Achtung! die embedded Version des Glassfish hat knapp 45MB, das Herunterladen kann also etwas dauern (wenn man wie ich nur ne 768kBit/s Leitung hat).
Nun kümmern wir uns um die Unit Tests. Dazu poste ich euch hier einen komplett funktionsfähigen Test den ich im Anschluss versuche zu erläutern. Da ich nämlich keinen kompletten Test in anderen Blogs finden konnte, sondern nur Codeschnipsel, hatte ich am Anfang noch mit einigen Exceptions zu kämpfen (naja, ich programmiere erst seit ein paar Wochen in Java, was will man erwarten).
package sample.test.controller;
import sample.controller.UserEntityFacade;
import sample.model.UserEntity;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.Assert;
public class UserEntityFacadeFixture {
public UserEntityFacadeFixture() {
}
public static EJBContainer container;
public static Context context;
public static UserEntityFacade facade;
@BeforeClass
public static void setUpClass() throws Exception {
Map properties = new HashMap();
properties.put(EJBContainer.MODULES, new File("target/classes"));
properties.put("org.glassfish.ejb.embedded.glassfish.installation.root", "/Applications/NetBeans/sges-v3/glassfish");
container = EJBContainer.createEJBContainer(properties);
context = container.getContext();
facade = (UserEntityFacade)context.lookup("java:global/classes/UserEntityFacade");
}
@AfterClass
public static void tearDownClass() throws Exception {
context.close();
container.close();
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void CreateUserEntity() {
UserEntity user = new UserEntity();
user.setUsername("jack");
user.setPassword("jack");
int count = facade.count();
facade.create(user);
Assert.assertEquals(count + 1, facade.count());
}
}
Hauptaugenmerk muss hier natürlich auf die Initialisierung des Containers gelegt werden. Dazu werden statische Variablen angelegt um den Container beim Start des Tests zu Starten und für alle Tests zur Verfügung zu haben. Am Ende der Tests wird der Container und der Context wieder geschlossen. Man beachte auch den import Bereich, da ich bei simpler Angabe von “public static Context context;” in einigen Codeschnipseln nämlich nicht rauslesen konnte das es sich dabei um den “javax.naming.Context” handeln soll. Aber wahrscheinlich ist das allen Java Experten klar.
Beim Erstellen des Containers wird der createEJBContainer Mehtode hier eine Hashmap mit Einstellungen übergeben. Dies ist an dieser Stelle wichtig, da wir JPA verwenden und daher das Verzeichnis vom Glassfish mit angeben müssen, damit der EJB Container die Konfiguration der JDBC Resourcen aus dessen Konfiguration lesen kann. Wird kein JPA verwendet, können die Einstellungen ganz entfallen, sprich es wird kein Parameter übergeben.
Anschließend holt man sich den Context und frägt daraus seine EJBs an. An dieser Stelle hatte ich auch wieder zu kämpfen. Mir war nicht ganz klar wie sich der JNDI Name aufbaut. Beim JBOSS hätte ich jetzt immerhin gewusst wo ich diesen nachschauen kann. Bei TheServerSide werden die mit EJB 3.1 eingeführten globalen JNDI Namen zwar erläutert, doch damit ließen sich meine Beans dennoch nicht auffinden. Nach langem Suchen bin ich dann auf die einfache und funktionierende Version oben gestoßen. Dabei ist der vordere Teil fest und nur der Name der Bean angehängt. Wenn mir jemand diesen Sachverhalt genauer erklären kann darf er sich in den Kommentaren dazu gerne auslassen ;-)
Der Rest des Listings dürfte hoffentlich keine Schwierigkeiten bereiten. Der Vollständigkeit halber hier noch die Blog Posts, die mir hierbei sehr hilfreich waren:
[1] Using the EJBContainer API with or without Maven (but with GlassFish v3)
[2] Unit Testing EJBs and JPA with Embeddable GlassFish
[3] EMBEDDING EJB 3.1 CONTAINER INTO YOUR UNIT TESTS – BOOT TIME: 5 SECONDS
[4] HOW TO UNIT-TEST EJB 3 …IN 0.8 SECONDS [SOURCE CODE INCLUDED]
[5] EJB Lite testing with JUnit and embeddable container
About this entry
You’re currently reading “Unit Tests von EJBs (mit JPA) mittels Embedded Glassfish v3 in NetBeans 6.8 und Maven,” an entry on BeagleOutOfBoundsException
- Published:
- 2.4.10 / 8pm
- Category:
- Java
- Tags:
3 Comments
Jump to comment form | comments rss [?] | trackback uri [?]