Testing is one of the most important aspects of software development. Without testing it would be difficult to determine if a piece of code worked properly, changes would have undetected consequences, and the quality of the code would generally be lower.
There are two major categories of testing generally recognised today: unit testing and integration testing. In the context of the GreenPages application, unit testing means testing a single class in isolation from other application code. This type of testing does not change at all when developing for Virgo and so the GreenPages sample does not include any unit tests.
In our application integration testing means testing an application or portion of an application with other code. This kind of testing does look a bit different when developing for Virgo. In most cases Virgo applications are made up of small bundles that consume services through the OSGi registry. The following highlights show how a single bundle and the entire GreenPages application can be integration tested outside the OSGi container.
One of the most common forms of integration testing is ensuring that the object relational mapping in an application is working properly. This kind of testing typically uses a data access object to retrieve data from a live database.
The greenpages.jpa.JpaDirectorySpringContextTests
class in the
src/test/java
source folder of the greenpages.jpa
project
is such a test case for the JpaDirectory
class.
The class uses JUnit to run the test and tests that a directory search completes
correctly. Rather than instantiate
this class directly in the test, the Spring Test Framework is used to instantiate and inject a
JpaDirectory
bean defined in the META-INF/spring/module-context.xml
file.
Spring Test Framework declarations are used to run the test with the
SpringJunit4ClassRunner
and configure the test with the files
classpath:/META-INF/spring/module-context.xml
and
classpath:/META-INF/spring/test-context.xml
:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/META-INF/spring/module-context.xml", "classpath:/META-INF/spring/test-context.xml" }) @TestExecutionListeners(value = DependencyInjectionTestExecutionListener.class) public class JpaDirectorySpringContextTests { @Autowired private Directory directory; @Test public void search() {
The test-context.xml
file in the
src/test/resources/META-INF/spring
folder defines two beans: a
DataSource
and a TestDataPopulator
:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" p:driverClassName="org.h2.Driver" p:url="jdbc:h2:.~/greenpages-db/greenpages" p:username="greenpages" p:password="pass" init-method="createDataSource" destroy-method="close" /> <bean class="greenpages.jpa.TestDataPopulator" init-method="populate"> <constructor-arg ref="dataSource" /> <constructor-arg value="file:../../db/db.sql" /> </bean>
These two beans provide a test DataSource
complete with test data.
The single bundle integration test provides a test implementation of its DataSource
dependency.
When integration testing, it is often a good idea to test the entire application outside of the container.
GreenPages includes such a test case for the
entire application, starting with the GreenPagesController
class
and descending all the way to a database.
Although it would be sensible for this test case to reside in a separate test bundle,
one of the bundles involved is a web bundle and so it is more convenient to locate the test case in the greenpages.web
project.
Since this test case will be testing the GreenPages application as a whole, it needs to depend on the bundles
that make up the application.
The pom.xml
file for the greenpages.web
project contains a dependency declaration for the greenpages.jpa
bundle:
<dependency> <groupId>com.springsource.dmserver</groupId> <artifactId>greenpages.jpa</artifactId> <version>${project.version}</version> <scope>test</scope> </dependency>
Note that the scope of the dependency is test
.
The GreenPagesSpringContextTests
class in the
src/test/java/greenpages/web
folder
contains Spring Test Framework declarations to run the test with the
SpringJunit4ClassRunner
and configure the test with the files
classpath*:/META-INF/spring/module-context.xml
,
file:src/main/webapp/WEB-INF/greenpages-servlet.xml
, and
classpath:/META-INF/spring/test-context.xml
. Note the use of
classpath*:
which causes Spring to look for files that match the specified path in all of the bundles on the classpath.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath*:/META-INF/spring/module-context.xml", "file:src/main/webapp/WEB-INF/greenpages-servlet.xml", "classpath:/META-INF/spring/test-context.xml" }) @TestExecutionListeners(value = DependencyInjectionTestExecutionListener.class) public class GreenPagesSpringContextTests {