Comparison Dialog in JUnit for Objects Other Than Strings

All major Java IDEs have a nice feature for dealing with string comparison in JUnit. When the assertion fail you can display the difference between the two strings in a popup. For example, here’s how it look like in Intellij IDEA:

String comparison in Intellj IDEA

It makes it easy to spot any differences between the two strings, even relatively large ones.

On the other hand when you compare other objects using assertEquals the only hint you get about the failure cause is the exception message that contains toString output for both objects. For example:

java.lang.AssertionError: expected:
<com.xyz.Person@c1cd1f[
  firstName=Piotr
  lastName=Jagielski
  website=piotrjagielski.com
]> but was:<com.xyz.Person@181afa3[
  firstName=Piotr
  lastName=Jagielski
  website=piotjagielski.com
]>

In the message above, have you noticed that the website name is misspelled? Imagine searching for such mistake in a much longer message. What people end up doing is either run a debugger, compare objects field by field or temporarily change assertions to something like assertEquals(expected.toString(), actual.toString()) to see the differences.

Wouldn’t it be nice to have the same popup when comparing objects other than strings? Actually, it’s possible with FEST Assert. I already wrote about how you can express assertions nicely and easily using it but I didn’t mention this particular reason I like it. Instead of writing assertEquals(expected, actual), use Assertions class from FEST Assert and write:

assertThat(actual).isEqualTo(expected)

In case of test failure you will be able to compare the output of toString method for both objects in the same way as when comparing strings:

person comparison using FEST Assert in Intellij IDEA

Now the spelling mistake is much easier to spot. It’s especially useful when comparing large object structures.

Posted in Java | Tagged , , , | 2 Comments

Google Guava vs Apache Commons for Argument Validation

It is an established good practice to validate method arguments at the beginning of the method body. For example you could check that the passed value is not negative before doing some calculation:

public int doSomeCalculation(int value) {
    if (value < 0) {
        throw new IllegalArgumentException("negative value");
    }
    ...
}

It can be written slightly shorter using the good old Apache Commons:

Validate.isTrue(value >= 0, "negative value");

More recently the same behavior can be achieved with Google Guava after statically importing the Preconditions class:

checkArgument(value >= 0, "negative value");

At surface it looks quite similar but usually the devil is in the details so I decided to take a closer look at both approaches. In this post I’m going to describe the differences between the two libraries regarding argument validation.

Static imports

The first immediately obvious difference is that Guava requires static import to look nice. Validate.isTrue() looks better than Preconditions.checkArgument(). Personally, I don’t mind static imports in my code. For some people it might be a small disadvantage though. Especially for those who don’t know how to work with them in the IDE yet. Also, if you work on some ancient project that still uses Java earlier than 5.0 you won’t be able to use Guava at all.

Types of exceptions

All methods from Validate class in Apache Commons throw IllegalArgumentException when validation fails. Sometimes it make sense to throw a different exception type. Guava make it possible. For example:

  • checkArgument throws IllegalArgumentException
  • checkState throws IllegalStateException
  • checkNotNull throws NullPointerException
  • checkElementIndex and checkPositionIndex throw IndexOutOfBoundsException, etc.

It’s obvious from the method name what exception gets thrown. I like this clear distinction in Guava.

Message parameters

It’s a good idea to give as much information about the failure as possible. For example if you validate that a number is positive you should add the actual number in the exception message if it’s not. In the example below it is done using the string concatenation directly:

Validate.isTrue(i > 0, "Should be positive but was: " + i);

In Commons Validate.isTrue() method you can pass additional parameter instead. It offers a performance benefit because the string concatenation is actually done only when the validation fails.

Validate.isTrue(i > 0, "Should be positive but was: ", i);

You can do a similar thing in Guava:

checkArgument(i > 0, "Should be positive but was: %s", i);

Additionally, Guava uses varargs for message parameters and you could also write:

checkArgument(i > MIN, "Expected more than %s, got %s", MIN, i);

In this case it’s also more readable than using string concatenation:

checkArgument(i > MIN, "Expected more than " + MIN + ", got " + i);

Validating collections and arrays

Apache Commons has some additional validations for collection and arrays that you won’t find in Guava:

  • allElementsOfType(Collection collection, Class clazz)
  • Validate.notEmpty(Collection collection)
  • Validate.notEmpty(Map map)
  • Validate.notEmpty(Object[] array)
  • Validate.noNullElements(Collection collection)
  • Validate.noNullElements(Object[] array)

This first one might be handy in legacy project not using generics. Others are generally useful.

On the other hand you can combine Guava Preconditions with any utility methods. In the example below I use the isNotEmpty method from Commons CollectionUtils in conjunction with Guava Preconditions to ensure that the list is not null and not empty:

checkArgument(isNotEmpty(list));

Assignment after validation

It’s common to assign a method argument to a field after validation. For example with Validate from Apache Commons you could write:

public Class(Object parameter) {
    Validate.notNull(parameter);
    this.field = parameter;
}

The checkNotNull from Guava Preconditions returns the validated reference. This allows validation and assignment in one line:

public Class(Object parameter) {
    this.field = checkNotNull(parameter);
}

Summary

In summary, here are the main advantages of both classes:

Apache Commons Validate

  • Works in old versions of Java
  • Readable without static imports
  • Collection and array validations

Google Guava Preconditions

  • Additional exception types
  • Better handling of message arguments
  • Easy assignment after not null check

Verdict

I prefer Guava Preconditions over Commons Validate for argument validation.

Posted in Java | Tagged , , , , | 20 Comments

Working With Static Imports in Eclipse

Eclipse has few features that make working with static imports almost as easy as it should be.

Add Import Keyboard Shortcut

Many people I work with were surprised that the “add import” shortcut works also for static imports. Just set the cursor on the static method, static field or enum constant, press Ctrl+Shift+M and it will be imported statically. I think it should also be available as a quick fix. This way more people would notice it.

Favorites

For most often used static imports it’s more convenient to add them as favorites. In order to do that go to Preferences -> Java -> Editor -> Content Assist -> Favorites. You can add static members and whole classes there.

Eclipse favorites menu

Once you add a static member or its class to the favorites it becomes available in code completion.

assertEquals with code completion in Eclipse

Imports Organization

You can control how static imports are organized when using the options above. There can be either a separate import for each static member or a wildcard character to import all members from a given type. It can be set in Preferences -> Java -> Code Style -> Organize Imports. By default the number of static imports needed for using the wildcard character is 99. If you set it to 1 Eclipse will always use the wildcard when adding static imports.

Additional Comments

If the code completion adds normal instead of static imports for favorites check whether “use static imports” option is set in Preferences -> Java -> Editor -> Content Assist.

Posted in Java | Tagged , , , | 1 Comment

Intuitive Behavior Verification With Mockito

When first I learned the technique of using mock objects in unit tests it was a quite easy concept to grasp. The implementation was a little bit harder to understand though. The first mock objects framework I worked with was EasyMock and I didn’t find it very intuitive. Let me explain what I mean.

Here’s an example from EasyMock documentation. It checks that the documentAdded method is called on a mock listener when addDocument method is called on the tested class.

@Test
public void testAddDocument() {
    mock.documentAdded("New Document");
    replay(mock);
    classUnderTest.addDocument("New Document", new byte[0]);
    verify(mock);
}

Most people who see it for the first time have no idea what’s going on. The key to understanding it is realizing that the mock object has two states. Initially the mock is in a record state and saves method calls as expected behavior (line 3). Calling replay on the mock switches it to a replay state (line 4). After this the tested method is invoked (line 5). When some unexpected method is called on the mock object at this stage an exception is thrown by default. When you call verify you make sure that the expected methods were actually invoked (line 6). Otherwise an exception will be thrown. The record and replay states can be thought as an analogy to magnetic tape. This pattern is known as expect-run-verify and it’s quite popular in mock objects libraries.

I was wondering why I have to write as many as three lines of code scattered across my test to simply verify that a method was called on the mock. The way it was done in EasyMock and most other mock objects libraries at the time seemed like just too much hassle.

Fortunately, Szczepan Faber and his friends served Mockito. Here’s how I can rewrite the test using it:

@Test
public void testAddDocument() {
    classUnderTest.addDocument("New Document", new byte[0]);
    verify(mock).documentAdded("New Document");
}

In Mockito you ask about the interactions after exercising the tested method similarly to expressing assertions in standard tests. There are no two states to think about. It feels much more intuitive. It’s definitely the best mock objects library in Java I know.

To learn more about Mockito see its documentation.

Posted in Java | Tagged , , , | 8 Comments

Local Maven Site in Multi-Module Project

Maven has a nice feature for generating project web sites. I like to use it especially for code coverage and static code analysis reports. For good explanation of setting it up is see an article at JavaWorld.

What might be surprising though is the way it is handled in multi-module project. When you run mvn site on such project, Maven will generate a site for each module independently. Unfortunately, links between module sites won’t work.

In order to make the links between modules work the site has to be deployed or staged. Most examples I’ve seen show how to deploy the site using SCP. I don’t work on any publicly available project so this is not what I wanted. In this post I’m going to explain few ways to create a local Maven site. I decided to post my findings because it was not immediately obvious for me how to do this from the documentation.

Site URL

In all options you have to add distribution management section in the top-level POM. The site URL will be different depending on the chosen option.

  <distributionManagement>
    <site>
      <id>site</id>
      <name>Project Site</name>
      <url>some URL</url>
    </site>
  </distributionManagement>

Stage

site:stage goal is intended to test the links between the modules before deploying the site. If you are going to use it only for local generation the URL doesn’t need to be valid so you can set it simply to “site”. Running the mvn site:stage from the root project directory should result in the site being created in target\staging\site with all links between the modules working correctly.

If you don’t want the site to be generated in the project-specific location use stagingDirectory parameter, for example mvn site:stage -DstagingDirectory=C:\project\site

Staging is relatively new option in Maven site plugin. It still has some issues and I was unable to use it in one of my projects. You can use the local deploy as a workaround.

Deploy

In addition to SCP you can also deploy the site using file protocol. In this case set the URL to something like file:///C:/project/site and run mvn site-deploy from the root project directory.

Creating the site in project-specific directory is a little bit more tricky using this technique. In order to make it work you can use ${user.dir} Java system property which points to current working directory and run mvn site-deploy from the root project directory. The URL may look like this: file:///${user.dir}/target/deployed-site. I also tried to use ${basedir} property but it didn’t work because its value was different for each module.

Additional comments

On several occasions I happened to see strange compilation errors during Maven site generation. I suspect that some reporting plugins retrieve project artifacts from the local repository under some circumstances. In order to ensure that they get the latest version I use install phase before running site. I also start with clean to ensure that the most recent version of compiled classes is used. The final command is either mvn clean install site:stage or mvn clean install site-deploy.

Posted in Java | Tagged , , , | Leave a comment

Custom Assertions in FEST Assert

I used to write the following code quite often in my unit tests:

assertEquals(2, list.size());
assertTrue(list.contains(element1));
assertTrue(list.contains(element2));

In order to reduce duplication these three lines of code can be extracted to a custom assertion:

assertContainsOnlyTheseElements(list, element1, element2)

Instead of writing your own assertions you can use the FEST Assert library. This is how you can express it in FEST:

assertThat(list).hasSize(2).contains(element1, element2);

Or even better:

assertThat(list).containsExactly(element1, element2);

Isn’t it beautiful? It reads almost like a natural language.

It’s also very easy to use because it requires only a single static import from org.fest.assertions.Assertions. The assertThat method is overloaded for multiple different types, each with specific assertions. The error messages in case of assertion failure are also quite user-friendly. For these reasons I prefer to use FEST Assert over Hamcrest for custom assertions.

Posted in Java | Tagged , , | 3 Comments

Less Verbose Java Collection Creation With Google Guava

Creating generic collections in Java is very verbose. Sometimes it may be hard to fit in one line:

Map<Integer, List<ClassWithLongName>> mapping
    = new HashMap<Integer, List<ClassWithLongName>>();

It can be shortened with a static factory method. Following the advice from Effective Java by Joshua Bloch some time ago I created a simple collection factory:

public class CollectionFactory {

    public static <K, V> HashMap<K, V> newHashMap() {
        return new HashMap<K, V>();
    }

    public static <T> List<T> newArrayList() {
        return new ArrayList<T>();
    }

    public static <T> Set<T> newHashSet() {
        return new HashSet<T>();
    }
}

After importing the newHashMap method statically, the declaration from the first listing can be shortened like this:

Map<Integer, List<ClassWithLongName>> mapping = newHashMap();

Such static factory methods are available in Google Guava library, a successor to Google Collections. Instead of your own method you can use Maps.newHashMap from com.google.common.collect package. There are also methods for creating other collection types and with additional parameters like initial capacity. See API documentation for the following classes in com.google.common.collect package:

  • Lists
  • Sets
  • Maps
Posted in Java | Tagged , , | Leave a comment

Maintainable HashCode and Equals Using Apache Commons

Java hashCode and equals methods can be tricky to implement correctly. Fortunately, all majors IDEs allow generating them. For example, this is how they look like for a class with two attributes when generated in Eclipse:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (firstName == null) {
        if (other.firstName != null)
            return false;
    } else if (!firstName.equals(other.firstName))
        return false;
    if (lastName == null) {
        if (other.lastName != null)
            return false;
    } else if (!lastName.equals(other.lastName))
         return false;
    return true;
}

It’s better than writing all this by hand but I still don’t like it. Here’s why:

  • It makes it way too easy to forget about updating them after adding a new field
  • It lowers the code coverage when not properly tested
  • It is just plain ugly

The first reason is the most important one. Having to remember about updating generated equals and hashCode methods when adding new fields increases the maintenance cost. Forgetting to do so may result in nasty bugs.

Because of that I never use generated hashCode and equals. I use builders from Apache Commons instead. In the most basic scenario they look like this:

@Override
public boolean equals(Object obj) {
    return EqualsBuilder.reflectionEquals(this, obj);
}

@Override
public int hashCode() {
    return HashCodeBuilder.reflectionHashCode(this);
}

They retrieve values using reflection from all fields except for transient and static ones. Most of the time this is precisely what I want. If you need some customizations check out the API documentation.

Posted in Java | Tagged , , , , | 2 Comments

Inspecting Java Non-Generated Sources in Intellij IDEA

I work on a relatively large project that consists of multiple Maven modules. They contain Java and Flex source files including many generated ones in both technologies. When I run code inspection on the whole project using Analyze -> Inspect Code… in Intellij IDEA I get many false positives.

The problem is that there are many warnings in the generated code that I’m unable to fix easily. Also, as of version 9 IDEA support for Flex still have some issues and often valid code is marked as error.

In order to make the code inspection usable in the project I created a custom scope for Java non-generated files. The scope language syntax reference is not very comprehensive as of time of writing but I was able to come up with this pattern:

file[*]:src/*/java//*

It allows me to inspect non-generated Java sources across all modules in directories conforming to Maven standard directory layout like src/main/java and src/test/java. Directories with generated files like target/generated-sources/jaxb are ignored.

Java non-generated scope in IDEA

Posted in Java | Tagged , , | 1 Comment

Java Collection Creation Templates in Intellij IDEA

How many times you wrote the following line of code in Java?

List<String> list = new ArrayList<String>();

Adding import statements, repeating the generic parameter…
For me it’s very annoying, so I created a template for that in my IDE. In this post I’m going to explain how to set up templates for creating collections in Intellij IDEA.

Go to Settings -> Live Templates and create a new template with the following text:

java.util.List<$type$> $name$ = new java.util.ArrayList<$type$>();

I chose “newlist” as an abbreviation for the template. You can also set default values for the type and the name in “Edit variables” dialog by typing them in double quotes in expression field.

After saving the template you can create a new array list easily by typing “newlist” and pressing Ctrl+J or the key you chose in the template dialog (Tab by default).

list creation template in IDEA

I also created live templates for other collections I use frequently – HashSet and HashMap using this technique.

Posted in Java | Tagged , , , | Leave a comment