Skip to main content

Testing Toolbelt: SpringJUnit4ClassRunner

The org.springframework.test.context.junit4.SpringJUnit4ClassRunner class is another implementation of the JUnit TestRunner class which is used to enable various features of Spring for every run of the test class and every test within it. To use the features provided by the SpringJUnit4ClassRunner class, you need to mark the class using the RunWith annotation using SpringJUnit4ClassRunner as its parameter.

In addition to the custom test runner, you will want to mark the class with the ContextConfiguration annotation. The ContextConfiguration annotation is used to mark classes which will automatically read a Spring configuration file and use it to create an ApplicationContext. By default, this file located at <package path>/<test class name>-context.xml. Use the locations argument to over-ride.

The ApplicationContext used by the Spring-integrated test will only be loaded once for the whole test class. This behavior can be over-ridden by annotating a test method with the DirtiesContext annotation, which causes the ApplicationContext to be reloaded after the test method completes.

Test Property Injection

Fresh versions of the properties for the test, including the class under test, can be automatically injected for every test, either by name or type. A test class property marked with the Autowired annotation will be automatically set by type from the test's ApplicationContext. However, if there are multiple instances of the property's type, it could be better to set the property by name. The Resource is used to mark test class properties which should be set by name from the test's ApplicationContext.

Transaction Management

With the declaration of a TransactionManager bean, and the use of the Transactional annotation, transaction boundaries are declarative and are automatically managed. Simply fire up the test and forget about whether or not your integration test changed the state of the database you're using to test.

The Transactional annotation is used within transactional Spring tests to mark test classes and methods which should have a transactional nature applied to them. When used to annotate a test class, a transaction context will be created before each test method is executed. After each test method, the transaction will be rolled-back. This will add the overhead of creating and managing a transaction for every test method in that class, so it is usually better to annotate the test methods with @Transactional instead. This will cause a similar effect to annotating the class, but only annotated test methods will be transactional. Usage of this annotation requires a TransactionManager named transactionManager to be defined in the test's ApplicationContext.

Similar in purpose to the Before and After annotations provided by JUnit, methods decorated with either the BeforeTransaction or AfterTransaction annotation will be run before/after any test method which is affected by the Transactional annotation (i.e. all methods in a class decorated with @Transactional, or each annotated test method when marked individually. Methods annotated with the BeforeTransaction or AfterTransaction annotations must be public and return no value.

Integration Test Helper Classes

When using the SpringJUnit4ClassRunner, you're given access to the ApplicationContext instance and a simplified interface for interacting with your integration test database through JdbcTemplate/SimpleJdbcTemplate.

spring-testing-sample.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ITSpringExample {
  @Resource Object dependencyByName;
  @Autowired String dependencyByType;

  @BeforeTransaction
  public void preTransaction() {
    System.out.println("before transaction");
  }

  @AfterTransaction
  public void postTransaction() {
    System.out.println("after transaction");
  }

  @Transactional
  @Test public void test1() {
    // before this test, a transaction will be created
    // after this test, the transaction will be rolled-back
  }

  @Test public void test2() {
    // no transaction will be created around this test
  }

  @DirtiesContext
  @Test public void test3() {
    dependencyByName = null;
  }
}

Comments

Anuj said…
Hey. If I want to initiate the execution of Spring test myself, lets say from a main class, how can I do it?
Ryan Ransford said…
@Anuj: Please take a look at this post for a quick answer.

Popular posts from this blog

Using MonoDevelop to Create an ASP.NET Web Service

NOTE : instructions below are for MonoDevelop 2.6 Beta 2 - built on 2011-04-06 03:37:58+0000 Getting Started Create a new ASP.NET Web Application in MonoDevelop: From the menu, select: File → New → Solution… Expand C# . Select ASP.NET → Web Application . Enter a name for the ASP.NET project that will be created in the solution in Name: . Change the root location for the solution in Location: , if desired. Change the name of the root solution in Solution Name: , if desired. The Results – I What you have after executing the new ASP.NET Web Application project wizard is a solution containing one ASP.NET Web Application project. In the default project view in MonoDevelop, you'll find the following items: Default.aspx – This is the default web form rendered and presented in the browser when http://<server>:<port>/ is accessed. Default.aspx.cs – This C# file contains the developer-created common code and event handlers which can be used to affect the process