Unit Tests

Overview

Automatised unit tests enables to rapidly control the source code. These test allow to validate various requirements, business rules and to control stability across time(non regression). The framework used to accomplish these tests is JUnit (http://www.junit.org)

Using JUnit

JUnit is set up in various ways.It is equally possible to exploit other utilities. Lutece uses the following way to take advantage of JUnit.

LuteceTestCase

The granularity of a test is a class. For each class to test, a derived class LuteceTestCase must be created and grouped in a set of tests to realise. The file structure of test classes must be reproduced as the sources of the application.

To realize the tests on the class :

  • src/java/fr/paris/lutece/plugins/myplugin/web/MyClass
A class must be created :
  • test/java/fr/paris/lutece/plugins/myplugin/web/MyClassTest

The class LuteceTestCase extends the abstract TestCase of the JUnit framework by initializing a set of Lutece services in the method implementation setUp(). It is thus possible, for all tests methods to access Lutece services : AppTemplateService, AppPropertiesService, AppConnectionService, etc.

Each test method inside a class is prefixed by "test" as imposed by the framework. This allows, by reflection, to dynamically find and launch each test in the class.

MockHttpServletRequest Object

To accomplish some tests, substitution(Mock objects) objects are necessary to simulate real objects. Example : In realizing the methods tests receiving a request object request as a parameter, it is impossible so simulate a HTTP client to provide this object request. The class MockHttpServletRequest, implements the interface HttpServletRequest and has accessors allowing it to add parameters, attributes, sessions and cookies so as to test a real situation.

import fr.paris.lutece.test.LuteceTestCase;
import fr.paris.lutece.test.MokeHttpServletRequest;

import javax.servlet.http.Cookie;

public class MyClassTest extends LuteceTestCase
{
    /**
     * Test getNameFromCookie
     */
    public void testGetNameFromCookie(  )
    {
        MokeHttpServletRequest request = new MokeHttpServletRequest(  );
        Cookie cookieName = new Cookie( "mycookie", "name" );
        Cookie[] cookies = { cookieName };
        request.setMokeCookies( cookies );
        assertEquals( getNameFromCookie( request ) , "name" );
    }  
    ...
}

Combination of tests (TestSuite)

JUnit offers a test combination mechanism based on TestSuites. For Lutece,a class AllTests is realized at each level of the package and provides a static method suite() which returns TestSuite containing all the tests of the package and the suites of the sub-packages. This mechanism enables launching of tests at all level of the package, by considering all tests from the sub-packages.

Here is an example of the AllTests class implementation

public final class AllTests
{
    /**
     * Constructor (private)
     */
    private AllTests(  )
    {
    }

    /**
     *  A set of tests
     * @return Test the tests
     */
    public static Test suite(  )
    {
        TestSuite suite = new TestSuite( "Test of the package fr.paris.lutece.plugins.myplugin" );

        //$JUnit-BEGIN$
        // Add tests of the current package 
        suite.addTest( new TestSuite( MyClassTest.class ) );
        
        // Add tests of sublevel packages
        suite.addTest( fr.paris.lutece.plugins.myplugin.business.AllTests.suite(  ) );
        suite.addTest( fr.paris.lutece.plugins.myplugin.web.AllTests.suite(  ) );
    
        //$JUnit-END$
        return suite;
    }
}