Chris Greenhalgh, 2007-02-06
It is (apparently) a *good thing* to develop your application
together with Unit tests. These allow you to:
Spring's dependency injection approach makes it relatively easy to
test objects and parts of the system without having to run/test the
whole web application.
This tutorial includes basic support for unit tests using JUnit. There are also specific
examples of testing code which makes use of EQUIP2.
The unit testing here is based on JUnit; refer to EQUIP2_WebApp_Configuring_and_Building
for which version of Junit to get (4) and where to put it (in lib/junit-4.jar)
> ant test
To create a new test make a new java source file in the test/
directory hierarchy (traditionally the package is the same as the
class(es) being tested, and the name is 'meaningful').
You will need to import org.junit.Test
and import static
org.junit.Assert.*. Each test should be a public method, which
you should tag with the (java 1.5) attribute org.junit.Test ('@Test'). The test method should
create any required data, run the test, and check for the correct
results using the org.junit.Assert.*
static methods, e.g. 'assertTrue(boolean)',
which requires the argument to be true
to mark success.
If the correct outcome is to throw an exception then tag the method
with the expected exception class as a parameter of the Test tag, e.g. '@Test(expected=
IndexOutOfBoundsException.class)'. See the JUnit documentation
(e.g. cookbook and Javadocs) for more details.
Add the name of your new test class to the argument list of the org.junit.runner.JUnitCore java
command in the build.xml file.
Now run the test(s) again.
See the Spring documentation (e.g. the web MVC tutorial and the
reference documentation (e.g. chapter 23)) for more suggestions on unit
testing controllers, etc. Spring also has some 'mock' objects whic
implement the HttpServletRequest/Response APIs for testing controllers
- see the Spring package org.springframework.mock.web.
See also the combined example, below.
The general idea is:
EQUIP2 has a number of different dataspace implementation. The web application normally uses the persistent version based on Hibernate over a RDBMS. However, for testing, other implementation can be used (avoiding the need to have a real database with suitable test data in it).
The tests directory in this tutorial includes a drop-in replacement for the normal IDAllocator class, equip2.spring.db.IDAllocator. This replacement will work with a transient (testing) dataspace, whereas the normal version depends on Hibernate and an underlying JDBC connection. There is a unit test for this replacement allocator: equip2.webapptutorial.testing.TestIDAllocator.
Some useful utility functions are collected into equip2.webapptutorial.testing.TestingUtils,
in particular newTransientDataspace(),
which creates a transient dataspace (!) and readXmlDump(IDataspace,File),
which reads the objects from an EQUIP2 XML dump into the dataspace.
The test equip2.webapptutorial.testing.TestSimpleDataspaceExample
includes an example of setting up a transient dataspace and testing
some simple dataspace operations.
Note that it is often possible to test controllers without a full
HTTP mock request, e.g. using a pre-populated command or form-backing
object.
If core game functionality is separated into distinct objects then
it may not be worthwhile recreating the full application/servlet
context, but rather the objects may be created and initialised directly.