Jul 20, 2008

Acceptance Test Driven Development training in Kiev

In august I'm going to conduct a training on the Acceptance Test Driven Development in Kiev. Date and agenda of the training was announced with help of Agile Ukraine. Most of the presented tools for automated acceptance testing will be related to Java language (have implementation for Java or native Java support). You are welcome!

Jul 19, 2008

Advanced EasyMock techniques

EasyMock is one of many mock libraries available for Java testing. Now it archive version 2.4 and is very powerful. For those of you who are not familiar with mock concepts start with Martin Fowler article. Detailed guide about EasyMock you can read here. I'm going to show some advanced techniques of using EasyMock in your tests.

Imagine that you have following document processing code:

public class DocumentService {
private DocumentProcessor processor;

public Document getDocument(long id) {
Document doc = //code to retrive document
processor.process(doc);
return doc;
}

public void setProcessor(DocumentProcessor processor) {
this.processor = processor;
}
}

public interface DocumentProcessor {
void process(Document document);
}

public class Document {
private String text;
private long wordsCount;

public Document(String text) {
this.text = text;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public long getWordsCount() {
return wordsCount;
}

public void setWordsCount(long wordsCount) {
this.wordsCount = wordsCount;
}
}

In your tests you want to check if changes made by processor really change returned document. To check this you want to set 'wordsCount' variable value to 5. You may create your own processor to do this:

public class DocumentServiceTest {
private DocumentService documentService = new DocumentService();
private DocumentProcessor processor = new DocumentProcessor() {
public void process(Document document) {
document.setWordsCount(5);
}
};

@Test
public void testGetDocument() {
documentService.setProcessor(processor);
Document document = documentService.getDocument(3);
Assert.assertEquals(5, document.getWordsCount());
}
}

But also you can use EasyMock (in my example I use Unitils to easy manage mocks):

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class DocumentServiceTest {
private DocumentService documentService = new DocumentService();

@RegularMock
private DocumentProcessor processor;

@Test
public void testGetDocument() {
expectDocumentProcessed();

documentService.setProcessor(processor);
Document document = documentService.getDocument(3);
Assert.assertEquals(5, document.getWordsCount());
}

private void expectDocumentProcessed() {
processor.process(isA(Document.class));
expectLastCall().andAnswer(new IAnswer<Object>() {
public Object answer() throws Throwable {
((Document) getCurrentArguments()[0]).setWordsCount(5);
return null;
}
});
replay(processor);
}
}

Why this is more powerful solution? Because you can change behavior of the processor in runtime and reuse the same mock in different tests with different behavior. Some times your dependencies are not so simple as document processor in my example and it is not so easy to extend or implements their methods (for example interface has 10 methods and you need only one of them). There is one more side effect of this usage - you have access to the parameters passed to the methods. You can save the parameter instance to use it in asserts or for other dependencies behavior mocking.

In 2.4 version of EasyMock 'capture' option was introduced to simplify work with method parameters. Document class from previous example doesn't have custom 'equals' method, so you can't use 'eq' method of EasyMock to check parameter of 'process' method. You can implement your own argument matcher (see IArgumentMatcher in the EasyMock guide) or use Unitils reflection comparison 'refEq', but another good option for you is to use new 'capture' option:

Capture<Document> capture = new Capture<Document>();
processor.process(and(isA(Document.class), capture(capture)));
replay(processor);

Document captured = capture.getValue();

These two techniques must be in your arsenal to use full power of EasyMock library and make your tests better. Develop with pleasure!

Jul 16, 2008

Design for scalability

If you develop large J2EE or WEB application using Java you should always think about scalability of your application (of course if you expect your application to be popular). Nobody tell you that you should scale your application initially, but take in mind that some architecture solutions may make it really hard to scale in the future. You have two common approaches: vertical and horizontal scalability. Both approaches has their requirements for code base to be applied effectively. I have found very interesting article on the www.theserverside.com about J2EE scalability written by Wang Yu from of Sun Microsystems. Article contains two parts: vertical and horizontal scalability. Take this information in mind when make architectural decisions. Develop with pleasure!

Jul 14, 2008

Make your tests excellent with Unitils

I am going to share my experience in using Unitils - framework that makes life easier. I have started to work with this framework from early release candidates and can't imagine my tests without it now. If you need to test application that use Hibernate, Spring, other ways of database access, but you don't want to write much test code and create some homegrown frameworks, then Unitils is your choice. If you already use some specific testing frameworks like EasyMock or DbUnit, but your tests are hard to create and maintain then Unitils will remove this pain for you.

Unitils started as a discussion group on unit testing. The result of these discussions is the list of guidelines that will be useful without Unitils itself. Then some people decide to build framework that will contains all in one, but be flexible enough to use it in different applications. So Unitils was born. To help developers with mapping guidelines to the framework there are tutorial and cookbook both published on the Unitils web site.

Unitils supports JUnit3, JUnit4 and TestNG and contains following modules:

- Spring module (for loading application contexts and retrieving and injecting Spring beans)
- Hibernate module (Hibernate configuration support and automatic database mapping checking)
- DbUnit module (test data management using DbUnit)
- Database module (unit-test database maintenance and connection pooling)
- EasyMock module (for creating mocks and lenient reflection argument matching)
- Inject module (for injecting (mock) objects into other objects)

Unitils configuration is very flexible and very small (if you are satisfied with default behavior). You can select any modules for your application and don't use others. Unitils work is based on annotations, so you will not need additional configuration files like except general settings file. Also Unitils provide to developers very useful assertion utilities, that based on reflection and support different modes for asserts.

Unitils has modular architecture so you can easy write your own modules to extend existing functionality. It is open source project so your modules may be included in future releases. General Maven repository contains last version of the framework so those of you who use Maven will not need manually install it. One important part is missed in Unitils - mocks for Java 'native' technologies like Servlets, JSP, JNDI and etc. I use a part of Spring framework (spring-test) for this purpose and it makes job very well.

From June 25, 2008 Unitils 1.1 became available. This release includes support of JPA, Spring transactions and complex database scripts structure. Also many integration bugs was fixed for database module.

I don't want to include examples for Unitils usage, you can find them in the tutorial or cookbook with detailed descriptions. Also there is useful video presentation with concrete samples. Make your tests better and your application code will be better. Develop with pleasure!

Jul 12, 2008

Evil 'System.currentTimeMillis()' and 'new Date()'

If you use TDD like me or just write unit tests for your code then you have already met issues with testing dates. There are two common ways to retrieve current time in Java: 'System.currentTimeMillis()' and 'new Date()'. Both of them make your code untestable. To illustrate this effect imagine that you test service for user registration and user record in the database contains registration date. When you create database record you put current date as registration date. But how to check that record is created correctly? Yes, perform assert operation. But what date should you place in your expected object? There is no easy answer. Of course you can check that registration date is in the interval of date when test was started and date when assert is performed. But then you will introduce additional variables and still can't assert full domain object using for equals. Similar issues exist for asserting method parameters and other parts of your testing. So I have created very useful utility class:

public class Clock {
private static long time;

private Clock() {
}

public static Date getCurrentDate() {
return new Date(getTimeMillis());
}

public static long getTimeMillis() {
return (time == 0 ? System.currentTimeMillis() : time);
}

public static void setTimeMillis(long millis) {
Clock.time = millis;
}

public static void resetTime() {
Clock.time = 0;
}
}

This class encapsulate all work with date creation and can be easy stubbed by setting internal time for particular usage. After test invocation it should be reset to disable stub behavior (DON'T FORGET TO DO IT). For some projects I extend this class with methods to retrieve shifted data to represent data in the future or in the past. If you need more complex logic (for example you will invoke date creation some times in the tested logic) then you may change 'time' static variable with 'DateTimeStrategy' class instance:

public interface DateTimeStrategy {
long getTimeMillis();
}

Then you will have more control on the data creation in your tests by implementing your own strategies. This approach not only helps me with testing but also encapsulate logic for dates creation in one place but makes my code clearer. I hate Java native implementation of work with dates and hope that in future it will be changed with something like Joda Time. I hope this approach will make your tests better. Develop with pleasure!

Be careful with your 'hashCode()'!

Every Java developer know that there are some methods common for all objects. One of them is 'hashCode()'. By default it returns internal address of the object, but should be overridden when your overrides another common method 'equals()'. Contract for the 'hashCode()' is following:

  • Whenever it is invoked on the same object more than once during
    an execution of a Java application, the hashCode method
    must consistently return the same integer, provided no information
    used in equals comparisons on the object is modified.
    This integer need not remain consistent from one execution of an
    application to another execution of the same application.

  • If two objects are equal according to the equals(Object)
    method, then calling the hashCode method on each of
    the two objects must produce the same integer result.

  • It is not required that if two objects are unequal
    according to the equals(Object) method, then calling the
    hashCode method on each of the two objects must produce
    distinct integer results. However, the programmer should be aware
    that producing distinct integer results for unequal objects may
    improve the performance of hashtables.



From this contract you can draw a conclusion that 'hashCode()' implementation should use only immutable fields of the object. Why? Lets create user domain object:

public class User {
private Long id;
private String name;

public User(String name) {
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public boolean equals(Object obj) {
return (this == obj) ||
(obj instanceof User && equals((User) obj));
}

public boolean equals(User that) {
EqualsBuilder builder = new EqualsBuilder()
.append(id, that.id)
.append(name, that.name);
return builder.isEquals();
}

public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder()
.append(id)
.append(name);
return builder.toHashCode();
}
}

I have used commons-lang to generate 'equals()' and 'hashCode()' but it doesn't matter. Now lets test if our 'hashCode()' is correct by running JUnit test:

public class UserTest {
@Test
public void testMutableName() {
Set users = new HashSet();
User user = new User("user");
user.setId(5L);
users.add(user);
user.setName("user2");
Assert.assertTrue(users.contains(user));
}
}

This test will fail because hash code of the user object was changed while user object itself was saved in the collection that uses it to save objects more efficiently.

Try to include in the 'hashCode()' only immutable fields, because you can have hidden issues not only with your own code but also with frameworks like Hibernate. If you don't have immutable fields, then be very careful and take described issues into account (recreate objects instead of changing them, don't use long live collections, return constant from 'hashCode()' or 'ID' field value). I hope this article will save you time for debugging. Develop with pleasure!

Jul 11, 2008

Effective Java (2nd Edition)


May 2008 brings us second edition of the Java bible "Effective Java" from Joshua Bloch. First edition takes first positions in many 'must read' lists for Java developers. This edition additionally includes features from Java 5 and 6. You can order it at Amazon.

FreeMarker integration with Intellij IDEA

Some of you who uses FreeMarker as your favorite template engine and Intellij IDEA as your favorite IDE will understand my pain. At the moment there is no support of FreeMarker in IDEA, so developers try to find other ways while waiting for IDEA 8.0 roadmap will be finished.

One of the best approaches is to use live templates - very powerful feature of the IDEA. Originally I have found basic templates with full explanation here. Then I refactor all templates to work with square brackets and add some new for Spring integration:

<template name="fm.spring.bind" value="[@spring.bind '$MODEL_KEY$' /]"
description="Sping bind function for the freemarker template"
toReformat="false" toShortenFQNames="true">
<variable name="MODEL_KEY" expression=""
defaultValue="" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="true" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>

<template name="fm.spring.expr" value="${spring.status.expression}"
description="Spring binded name for the freemarker template"
toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="true" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>

<template name="fm.spring.url"
value="[@spring.url relativeUrl=$RELATIVE_URL$ /]"
shortcut="SPACE"
description="Insert URL to another page of the application"
toReformat="false" toShortenFQNames="true">
<variable name="RELATIVE_URL" expression=""
defaultValue="" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="true" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="true" />
</context>
</template>

<template name="fm.spring.val" value="${spring.status.value}"
description="Spring binded value for the freemarker template"
toReformat="false" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="true" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>

These templates help me every day and save time to manual typing. May be it will be starting point of using live templates for some of us. Develop with pleasure!

Select implementation of Spring bean in runtime

Some of you who uses Spring in your application as dependency injection framework or as development platform may be need change implementation of one particular dependency in runtime. Some examples of this need: integration testing with fake external subsystem, local and remote versions of services, mock implementation to speed up development.

I have found very useful to have such option in my applications and implemented special factory bean for this purpose:

public class SelectImplementationFactoryBean implements FactoryBean {
private String key;
private Map<String, Object> implementations;

public Object getObject() {
Object impl = implementations.get(key);
if (impl == null) {
throw new IllegalStateException("There is no implementation for key = "
+ key);
}
return impl;
}

public Class getObjectType() {
return getObject().getClass();
}

public boolean isSingleton() {
return false;
}

@Required
public void setKey(String key) {
this.key = key;
}

@Required
public void setImplementations(Map<String, Object> implementations) {
this.implementations = implementations;
}
}

Simple enough but very powerful. I will demonstrate how to use it to control database properties for integration with Hibernate:

<bean id="hibernateProperties" class="com.example.SelectImplementationFactoryBean">
<property name="key" value="${database.dialect}"/>
<property name="implementations">
<map>
<entry key="postgre">
<util:map map-class="java.util.Properties">
<entry key="hibernate.hbm2ddl.auto" value="validate"/>
<entry key="hibernate.show_sql" value="true"/>
<entry key="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect"/>
<entry key="hibernate.default_schema" value="test"/>
<entry key="hibernate.cache.use_second_level_cache" value="false"/>
<entry key="hibernate.cache.provider_class"
value="org.hibernate.cache.NoCacheProvider"/>
</util:map>
</entry>
<entry key="hsqldb">
<util:map map-class="java.util.Properties">
<entry key="hibernate.hbm2ddl.auto" value="validate"/>
<entry key="hibernate.show_sql" value="true"/>
<entry key="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<entry key="hibernate.cache.use_second_level_cache" value="false"/>
<entry key="hibernate.cache.provider_class"
value="org.hibernate.cache.NoCacheProvider"/>
</util:map>
</entry>
</map>
</property>
</bean>

Now to switch your tests to another database you should change value of the property database.dialect between postgre and hsqldb (it can be configuration properties file or system property). I hope it will save your time. Develop with pleasure!

Jul 10, 2008

Access SVN version and build date from maven

Sometimes we need to show or save information about application build. This information may include sources version (from VCS that you use), build date, database versions, etc. If you build your application with Maven there is easy way to access this information.

To do this check buildnumber-maven-plugin. This plugin is used to build extended build version. To access SVN version and build timestamp (not formatted date) you need to add following plugin configuration to maven pom.xml:

<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<configuration>
<buildNumberPropertyName>sources.version</buildNumberPropertyName>
<timestampPropertyName>build.timestamp</timestampPropertyName>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

These variables may be used to build project version, to label project artifacts or just to provide this information to end user like in following example:

- Add file version.properties to you maven module resources:

application.sources.version=${sources.version}
application.build.date=${build.timestamp}

- Add filtering section for this file to the maven pom.xml:

<resources>
....

<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>version.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>

Now you have more control on application version. Develop with pleasure!