Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
You should be familiar with [JUnit|http://www.junit.org/] as it is what OpenMRS uses for unit testing. For my test, I used JUnit4. Please see [The unit testing tutorial|http://openmrs.org/wiki/Unit_Testing] and [The module unit testing tutorial|http://openmrs.org/wiki/Module_Unit_Testing] for more information. It is assumed for the sake of this tutorial that you have read and understand those.

This is a brief tutorial on how to unit test a servlet using [httpunit|http://httpunit.sf.net/]. There are two examples that exist in the OpenMRS subversion repository. I will discuss how to test HTTP requests.

First, you must add the following jar files to your module's  classpath. These are included in htmlunit's distributed zip file in the  jar directory.

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=1]\]

h1. Classpath

In lib-common add:
* xercesImpl-2.6.1.jar

Then in lib add the following:
* js-1.6R5.jar
* nekohtml-0.9.5.jar
* httpunit.jar

Add these to your eclipse classpath. For the method I used, you must deploy your module, and it must be running in OpenMRS.

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=2]\]

h1. Writing your test

A fair warning, I've written my test in [Groovy|http://groovy.codehaus.org/], however the concepts are all there, and should be obvious.

Now that you have your classpath set up, it is assumed that you  will allow eclipse to manage your imports for you, so I will only show  you one method for the sake of brevity. Then I will explain it line by  line.WebConversation wc
 
    @After
    void cleanUp() {        wc = null    }
The above line is needed so that we can clean up after we finish  testing. That should be the first method in your test class. Now let's  write our first test method, I'm testing my [AJAX Servlet|http://dev.openmrs.org/browser/openmrs-modules/groovyforms/web/src/org/openmrs/module/groovyforms/web/servlet/ajax/CreateGroovyFormAjaxServlet.groovy] which is responsible for validation/generation of the controller/view for the [Groovy Forms Module|http://openmrs.org/wiki/GroovyForms_Module].

I am only going to post one test method here, for the full class see [this link|http://dev.openmrs.org/browser/openmrs-modules/groovyforms/test/org/openmrs/module/groovyforms/web/servlet/ajax/CreateGroovyFormsAjaxServletTest.groovy?rev=5053].  It should give you the overall gist. Assume for the sake of this test   method that a static import exists for assertTrue and assertEquals (as  that is the case in my test class.)@Test
    void testCheckSyntaxForModel() {
        wc = new WebConversation()
        def rq = new PostMethodWebRequest("http://localhost:8080/openmrs/moduleServlet/groovyforms/createGroovyForm")
        rq.setParameter "clazz", "class MyForm { }"
        rq.setParameter "validate", "true"
        rq.setParameter "name", "My Form"
        rq.setParameter "version", "1.0"
        def response = wc.getResponse(rq)
        assertEquals "<result>true</result>", response.text
 
        // test when no class definition is given
        rq.setParameter "clazz", ""
        response = wc.getResource(rq)
        assertEquals "<result>false</result>", response.text
 
        // test invalid syntax
        rq.setParameter "clazz", "class MyForm { String }"
        wc = new WebConversation()
        response = wc.getResponse(rq)
        assertTrue "Should be true", response.text.indexOf("Exception") > 0
    }
What's going on here? Let's see.
# wc = new WebConversation()
## This is how we mock the browser session
# def rq = new PostMethodWebRequest("[http://localhost:8080/openmrs/moduleServlet/groovyforms/createGroovyForm|http://localhost:8080/openmrs/moduleServlet/groovyforms/createGroovyForm]")
## Next, we "fake" a form POST operation.
# The next few lines, i just define the request parameters.
# def response = wc.getResponse(rq)
## Now we actually "submit" the request.
# Finally, I check that the syntax is correct  by retrieving the the text from the response (using response.text). It is valid.

Then after that, I check to see if it returns the correct response if  no code is given; that works. Finally, I check to see that giving  invalid code returns an exception, and indeed it does.

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=3]\]

h1. Final Notes Regarding Groovy

# When you see "response.text" it is *NOT* direct field access, groovy calls the getter for that field, in this case getText().
# When you see "def" it is using duck-typing, the type is inferred based on the value to the right.
# Parenthesis are optional, except in the case of no-arg methods.
# Semi-colons are optional, except when you have multiple statements on the same lines.

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=4]\]

h1. Other Links

*  [ODA Logic Web Service Unit Test|http://dev.openmrs.org/browser/openmrs-modules/logicws/test/org/openmrs/module/logicws/test/LogicWsHTTPtest.java]
**  [Servlet being tested|http://dev.openmrs.org/browser/openmrs-modules/logicws/web/src/org/openmrs/module/logicws/web/RestServlet.java]

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=5]\]

h1. Questions??

Hop onto [IRC|http://openmrs.org/wiki/IRC]; my nick is r0bby, and I'll be happy to answer any questions, my contact info is also available on my [User page|http://openmrs.org/wiki/User:r0bby], feel free to contact me with questions.

\[[edit|http://archive.openmrs.org/index.php?title=Unit_Testing_Servlets&action=edit&section=6]\]

h1. FAQ

* What is @After
** The @After annotation tells JUnit to run this method after each test is complete.
* What is @Test
** The @Test annotation tells JUnit to that this method is a test, and should be run.