4

I'm relatively new to JAX-RS, JPA, GlassFish, Java DB, and NetBeans, and I'd like to write unit tests for my code. [Version numbers are at the bottom.] However, I'm stuck on where to begin. I've done a good bit of searching, but I don't yet have a clear understanding of how to set up an embedded test of my code. I'm using NetBeans, but my question is general. I wish I could form my question more clearly, but this is the best I could do. So far I've found the following possible pieces (more like hints at this point).

o I want to set this up without Maven, but this means I must install the embedded jars manually. Q: Where do I find them?

o Create versions of my config xml files (glassfish-resources.xml and persistence.xml) that specify embedded versions of GlassFish and Java DB. Q: But how do you tell NetBeans to use those for testing rather than production ones that rely on the installed version of them?

I think persistence.xml would look something like this (from using hibernate with embedded derby):

  <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
  <property name="javax.persistence.jdbc.url" value="jdbc:derby:test"/>
  <property name="javax.persistence.jdbc.user" value="root"/>
  <property name="javax.persistence.jdbc.password" value="root"/>

o Create a custom Glassfish domain configuration file ( Embedded GlassFish ignores Maven test resources ). Q: What should this look like? I have domain.xml from the default domain1 that was created with my NetBeans install, but there's a lot to it.

o Once my project has access to the embedded files, and it is configured to use them, what should my JUnit harness look like? http://jersey.java.net/nonav/documentation/latest/client-api.html#d4e759 says:

protected void setUp() throws Exception {
  ...
    glassfish = new GlassFish(BASE_URI.getPort());
    ScatteredWar war = new ScatteredWar(...);
    glassfish.deploy(war);
  ...

However, I've also seen EJBContainer mentioned, e.g., (from http://docs.oracle.com/javaee/6/tutorial/doc/gkcqz.html ):

@BeforeClass
public static void initContainer() throws Exception {
  ec = EJBContainer.createEJBContainer(); ctx = ec.getContext();
}

o I'm using JPA, so I need access to the PersistenceContext/EntityManager. Currently I look it up via:

new InitialContext().lookup("java:module/<jax-rs resource name>");

But I've also seen:

    emf = Persistence.createEntityManagerFactory("chapter02PU");

Q: What's the right way to get a hold of this?

I would really appreciate your help.

  • Versions:
    • GlassFish Server Open Source Edition 3.1.2 (build 23)
    • Java DB/Derby: 10.8.1.2 - (1095077)
    • NetBeans IDE 7.1 (Build 201112071828)
Community
  • 1
  • 1
Matthew Cornell
  • 4,114
  • 3
  • 27
  • 40

2 Answers2

5

OK, I got the GlassFish infrastructure working, and was able to successfully create tests for a simple servlet and a simple JAX-RS service. It took some searching to figure this out, so I'll share here in case others can use it. I haven't yet delved into JPA testing, but one step at a time. I'm new to StackOverflow, so I don't know the accepted protocol for sharing a lot of code in an answer, but here goes: How to boot a GlassFish embedded instance that serves a simple servlet and a JAX-RS resource, then tests them. Packages omitted. Embedded javadocs: http://embedded-glassfish.java.net/nonav/apidocs/

1. Configure JAX-RS:

package org.netbeans.rest.application.config;
@javax.ws.rs.ApplicationPath("resources")
public class ApplicationConfig extends javax.ws.rs.core.Application {
}

2. Define the resource: package rest;

@Path("generic")
public class GenericResource {

public static final String MESSAGE = "hi there";

public GenericResource() {
}

@GET @Produces(MediaType.TEXT_PLAIN)
public String sayHi() {
    return MESSAGE;
}
}

3. Define the servlet:

package servlet;

@WebServlet(urlPatterns = {"/hello"})
public class HelloWebServlet extends HttpServlet {

 public HelloWebServlet() {
 }

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
    PrintWriter pw = res.getWriter();
    try {
        pw.println(GenericResource.MESSAGE);
    } catch (Exception ex) {
        e.printStackTrace();
    }
}
}

4. Define the tests, using the Jersey REST client, JUnit 4, http://download.java.net/maven/glassfish/org/glassfish/extras/glassfish-embedded-all/3.1.1/glassfish-embedded-all-3.1.1.jar

package rest;

public class NewServletTest {

private static final Logger LOG = Logger.getLogger(NewServletTest.class.getCanonicalName());
private static GlassFish glassfish = null;
private static final String WEB_APP_NAME = "RestTemp";
private static final String BASE_URI = "http://localhost:" + 8080 + "/" + WEB_APP_NAME;
private static final String REST_URI = BASE_URI + "/" + "resources" + "/" + "generic";

public NewServletTest() {
}

@BeforeClass
public static void startServer() {
    try {
        GlassFishProperties gfProps = new GlassFishProperties();
        gfProps.setPort("http-listener", 8080); // NB: not sure where name comes from - a standard property?

        glassfish = GlassFishRuntime.bootstrap().newGlassFish(gfProps);
        glassfish.start();

        Deployer deployer = glassfish.getDeployer();
        ScatteredArchive archive = new ScatteredArchive(WEB_APP_NAME, ScatteredArchive.Type.WAR);
        File buildDir = new File("build", "classes");         // NB: location depends on IDE setup
        archive.addClassPath(buildDir);
        deployer.deploy(archive.toURI());
    } catch (GlassFishException ex) {
        LOG.log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        LOG.log(Level.SEVERE, null, ex);
    }
}

@AfterClass
public static void shutDownServer() {
    if (glassfish != null) {
        try {
            glassfish.stop();
            glassfish.dispose();
            glassfish = null;
        } catch (GlassFishException ex) {
            LOG.log(Level.SEVERE, "tearDownClass(): exception: ", ex);
        }
    }
}

@Before
public void setUp() {
}

@After
public void tearDown() {
}

@Test
public void testPing() throws MalformedURLException, IOException {
    URL url = new URL(BASE_URI + "/hello");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.connect();

    InputStream inputStream = conn.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
    assertEquals(GenericResource.MESSAGE, br.readLine());
}


@Test
public void testGet() {
    WebResource r = Client.create().resource(REST_URI);
    ClientResponse cr = r.accept(MediaType.TEXT_PLAIN).get(ClientResponse.class);   // GET
    String crEntityStr = cr.getEntity(String.class);
    ClientResponse.Status crStatus = cr.getClientResponseStatus();
    assertEquals(GenericResource.MESSAGE, crEntityStr);
    assertEquals(ClientResponse.Status.OK, crStatus);
}
}

To create this project in NetBeans:

  1. select New Project > Java Application. take defaults
  2. delete JavaApplicationTemp
  3. use NetBeans to create above files in the Source Packages IDE folder (will go into src/):
    • org.netbeans.rest.application.config.ApplicationConfig
    • rest.GenericResource
    • servlet.HelloWebServlet
  4. select New > JUnit Test. take defaults, select JUnit 4.x
  5. delete NewEmptyJUnitTest
  6. use NetBeans to create above file in the Test Packages IDE folder (will go into test/):
    • rest.NewServletTest
  7. edit the project's property and add glassfish-embedded-all-3.1.1.jar to the Libraries > Compile category
  8. select Run > Test Project. ideally you'll see three passed tests!

Hope that helps!

Matthew Cornell
  • 4,114
  • 3
  • 27
  • 40
0

If you are using Netbeans, then just install the JUnit plugin. Once installed created a package to hold your test classes, right click the package you just created and choose "New->Other". This will pop up a menu with all the file types installed. Browse down to the JUnit package, and in the right pane choose "JUnit Test".

This will create a JUnit class stub for you. From here you just need to define a method for each test, and annotate them with @Test.

I would suggest starting off with just one. Once you're written a simple test then go up the to the "Run" menu at the top of the application and choose "Test Project ([yourAppName])".

Hopefully this will set you on the right path.

hypno7oad
  • 1,441
  • 1
  • 19
  • 28
  • Thank you, hypno7oad. I'll update the question to show that I'm comfortable with structuring the tests using JUnit, and it's the GlassFish side of things that I need help with. – Matthew Cornell Mar 12 '12 at 18:28