Search |
||
A Simple Servlet for Running JUnit in GlassfishPosted by cayhorstmann on February 14, 2009 at 8:37 PM PST
When teaching unit testing in the context of a simple EJB3.1 application, I was looking for an easy way of testing managed beans and session beans inside Glassfish. Of course, one can test out-of-container or use an embedded container (but I didn't quite figure out how to do that with Glassfish v3—I'd appreciate hints), or a mock container (but that seemed to require a bit of setup). I hit upon a scheme that I had not seen elsewhere: put the unit tests in the container and trigger them with a servlet that reports the outcomes. Advantages:
Here is how to do it. Add the JUnit 4 JAR to Add the following servlet to your WAR file: package myapp.servlets;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.internal.JUnitSystem;
import org.junit.runner.JUnitCore;
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String className = request.getParameter("class");
response.setContentType("text/plain");
OutputStream out = response.getOutputStream();
final PrintStream pout = new PrintStream(out);
new JUnitCore().runMain(new JUnitSystem() {
public PrintStream out() { return pout; }
public void exit(int arg0) {}
}, className);
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
Add the following entries to <servlet>
<servlet-name>TestServlet</servlet-name>
<servlet-class>myapp.servlets.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
Write your JUnit test case in the usual way. For example, here is a test for a session bean: package myapp.session;
import static org.junit.Assert.assertEquals;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.junit.Before;
import org.junit.Test;
import myapp.entity.Person;
public class UserSBTest {
private UserSB userSB;
@Before public void init() throws NamingException {
InitialContext context = new InitialContext();
userSB = (UserSB) context.lookup("java:global/MyApp/UserSB");
}
@Test public void testAddUser() {
Person p = new Person();
p.setFirstName("Fred");
p.setUsername("fred");
userSB.save(p);
Person q = userSB.find("fred");
assertEquals(p.getFirstName(), q.getFirstName());
userSB.removePerson("fred");
}
}
Unfortunately, you can't just have the container inject the session bean. @EJB private UserSB userSB; // Doesn't work when JUnit loads the class When JUnit loads the class, it doesn't deal with EJB annotations. Then point your browser to
Proverbial exercise to the reader: Add a green bar when the test cases pass. »
Comments
Comments are listed in date ascending order (oldest first)
Submitted by euxx on Sat, 2009-02-14 22:24.
Apache Cactus has been there for years http://jakarta.apache.org/cactus/
Submitted by cayhorstmann on Sun, 2009-02-15 07:17.
Thanks, but Cactus is much more heavyweight than what I was looking for. Maybe because it has been there for many years :-)
Submitted by stephenconnolly on Mon, 2009-02-16 10:00.
You could also have a look at easygloss.dev.java.net
It could certainly handle injecting your injectables for you ;-)
It also might be easier, with EasyMock, for running the tests outside of the servlet container
Submitted by cayhorstmann on Mon, 2009-02-16 10:28.
Thanks for the tip about easygloss. Of course, what I really want is not to have to worry at all but find a way for the container to do the injection. Is there some way to locate the ambient app server, hand it an object, and say "hey, inject this"?
Submitted by bvansomeren on Tue, 2009-02-17 00:10.
Hi,
That's actually a nice way of doing it.
I've worked on projects where we had a whole maven build that used a small container (OpenEJB) to load our EJB 3.0 components and test them.
Setting it up was a pain as you can imagine.
Now I'm looking for a way to do something simpler as part of a pet project of mine and this fits the bill nicely.
You could even run this during deploy and throw a fat Runtime exception when a test fails and thus bail out of the deploy.
Thanks
|
||
|
|