Discussions

The Unitils team has announced the release of Unitils 1.0, aimed at making unit testing easy and maintainable.
Unitils offers general testing utilities (assertion using reflection), features that help with testing the persistence layer, and testing with mock objects. Unitils builds further on existing frameworks like DbUnit and EasyMock, and can be used with JUnit versions 3 and 4 as well as with TestNG.
Most of the added value is in the field of persistence layer testing, offering features like simplifying the insertion of test data into the database, using a very simple XML data file format (based on the popular database testing framework called Dbunit). With Unitils, you can fill your test database with data by simply annotating a test class or test method:@DataSet
public void UserDaoTest extends UnitilsJUnit4 {
@Test
public void testFindUsersOlderThan() { ... }This will make sure a dataset with the same name as the class gets inserted into the test database before each execution of a test. An XSD or DTD is generated and automatically updated, which can be used for validation and auto-completion. An example datafile:<!--?xml version='1.0' encoding='UTF-8'?-->
Definition of test data is a lot easier with database constraints such as foreign key and not null constraints disabled. Think about the amount of data you have to add to your database that you actually don't need, just to satisfy these constraints. With Unitils, you can disable these constraints automatically. Also, a simple system is offered to automatically maintain test databases: You simply store the scripts that define your database structure in a directory. If you add a new script, it is applied automatically. If an existing script changes, the database is dropped and recreated from scratch. Unitils also updates sequences and identity columns to have a value higher than a certain treshold, so that generated keys don't clash with IDs that you use for testing.
Comparing the result of a query with the expected result is a lot more easy with the ReflectionAssert utility. Using ReflectionAssert.assertRefEquals(expected, actual), all fields of the actual object are compared recursively with the expected one. Very useful are the leniency options of this tool, such as ignoring values that are null in the expected object and ignoring the order of elements in collections.
Other features of Unitils are:
- Ability to run each test in a transaction and commit or rollback at the end.
- Integration with Hibernate: easy SessionFactory configuration, test-bound Sessions and a test that checks the mapping of all entities with the database
- Integration with Spring: inject spring-configured beans in your tests, integrate with a spring defined Hibernate SessionFactory or transaction manager.
- Support for mock objects based on EasyMock: Injection of mocks into fields annotated with @Mock, argument matching using reflection assert, injection of mocks into the tested object using an @InjectInto annotation.
To find out more on Unitils, visit www.unitils.org. You can find a quick start guide in our cookbook and a detailed description of all features in the tutorial.

Is it compatible with Spring 2.5? Can I use @RunWith(SpringJUnit4ClassRunner.class)? And the TransactionalTestExecutionListener to be able to use Spring's @Transaction annotation in the test methods?

Unitils currently doesn't integrate with Spring's brand new TestContext framework. At the moment we developed Unitils' core functionality, Spring didn't support any other test framework than JUnit 3.
We will provide integration in the future, so that you can use the two frameworks together. You can however also use Unitils' transaction management and Spring-integration features to have the same effect:

Load an ApplicationContext by annotating the test with @SpringApplicationContext, and annotate fields on which you want Spring-configured beans to be injected with @SpringBean("myBeanId"), @SpringBeanByName or @SpringBeanByType

Annotate the test with @org.unitils.database.annotations.Transactional(TransactionMode.ROLLBACK) to run each test in a transaction and rollback at the end. The system will make use of a PlatformTransactionManager that it can find in the application context (if not using Spring, a very simple Unitils-specific transaction manager is used)

Is it compatible with Spring 2.5? Can I use @RunWith(SpringJUnit4ClassRunner.class)?
And the TransactionalTestExecutionListener to be able to use Spring's @Transaction annotation in
the test methods?

As Filip pointed out, Unitils and the Spring TestContext Framework are not currently integrated. Due to the design of JUnit 4's Runner and @RunWith architecture, many third-party developers (e.g., Spring and Unitils) are essentially forced to provide a custom Runner in order to offer substantial value-add over and above the standard JUnit feature set. If JUnit were to provide a listener architecture for "instrumenting" the test execution life cycle, there would likely be no need for custom runners; however, since that is not yet the case, you currently have to choose which runner to use, for example SpringJUnit4ClassRunner or UnitilsJUnit4TestClassRunner.
One of the benefits of using the SpringJUnit4ClassRunner is that it provides support for standard Spring annotations such as @Transactional, @Autowired, etc. (as well as test-specific annotations like @Rollback, @NotTransactional, @BeforeTransaction, @AfterTransaction, etc.). Unitils provides similar support via its own @Transactional and @SpringBean* annotations. Thus, although both frameworks provide some overlap in terms of functionality for dependency injection and transaction management, with the Spring TestContext Framework, you can use the same annotations in both your application and test code. Spring also provides annotation-driven DI via @Resource (JSR-250) and @PersistenceContext / @PersistenceUnit (JPA). For additional information, check out Spring's common test annotations and TestContext-specific annotations.
I know that Filip and Tim are looking into providing some integration points between the two frameworks to possibly allow Unitils functionality to be used via custom TestExecutionListeners in the Spring TestContext Framework. So stay tuned for further developments and feel free to make recommendations to both teams.

Looks like a good tool for testing DB.. (I especially like the part about dropping and re-creating a db).
However, what I like right off the bat are is the Reflection based Assertions.. I could use these outside of Unit Testing also.
Is there anyway to IGNORE certain properties in a comparison. So for instance, it would be great if assertRefEquals also took a string or a collection of Properties that it could ignore in both the beans it is comparing.
Is there anyway to do that currently?
Pankaj

Is there anyway to IGNORE certain properties in a comparison. So for instance, it would be great if assertRefEquals also took a string or a collection of Properties that it could ignore in both the beans it is comparing.

Ignoring a listed set of properties is not supported by default. We try to keep a limited set of useful features, not adding anything unless there are some valid use cases for it in the testing domain.
However it's easy to use the reflection comparison outside a testing context, and tailor it for your own needs. Behind the scenes it is implemented as a chain of responsibility consisting of ReflectionComparators. Each of these comparators implements comparison of objects of some type and/or some leniency option (e.g. there's a LenientOrderCollectionComparator that compares collections and ignores their order), so you can easily implement a ReflectionComparator that ignores certain properties, and assemble a custom comparator chain that does what you want it to do.

TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations technology projects - with its network of technology-specific websites, events and online magazines.