April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Write More Understandable Java Tests with Matcher Objects and FEST-Assert, Page 3

  • August 30, 2010
  • By Shekhar Gulati
  • Send Email »
  • More Articles »

Hamcrest vs. FEST-Assert

FEST-Assert is a Java 5 library that provides a fluent interface for writing assertions. Both Hamcrest and FEST-Assert aim to improve the readability and maintainability of tests, but they are implemented in a different way. FEST-Assert uses chaining to build complex assertions whereas Hamcrest uses nesting. Let’s compare a test written using Hamcrest with one written using FEST.

Using Hamcrest


@Test
public void shouldMatchCollectionHasSizeAndContainsMultipleItems() {
List words = Arrays.asList("available", "avenge", "avenue", "average");
assertThat(words, hasItems("available", "avenge", "avenue"));
assertThat(words,hasSize(3));
}

Using FEST-Assert


@Test
public void shouldMatchCollectionHasSizeAndContainsMultipleItems() {
List words = Arrays.asList("available", "avenge", "avenue", "average");
assertThat(words).hasSize(3).contains("available", "avenge", "avenue");
}

With Hamcrest, you cannot nest two matchers (i.e. hasItems and hasSize), whereas with FEST-Assert you can chain the assertions together. Whether you should use Hamcrest or FEST-Assert depends on your style of programming, but I find FEST-Assert easier to. I prefer FEST-Assert because:

  1. Less conceptual weight: When you use Hamcrest, you have to know all the different matchers available in the Hamcrest library. But with FEST-Assert, you have to know just one method (assertThat) and depending upon your parameter the library will give you a set of methods to work on. This reduces the conceptual weight of FEST-Assert.
  2. Chaining is easier to use than nesting: To build complex assertions in Hamcrest, you need to nest one matcher inside another matcher, which is sometimes confusing. Using Hamcrest, it is your responsibility to find which matcher to use for nesting. But with FEST-Assert you just have to type a period (.) and you will get the possible assertion methods for the value passed to assertThat.

FEST-Assert is undoubtedly much easier to use than Hamcrest but it doesn't come bundled with JUnit and you can't write assertions that can test the elements of a collection. For example, you can’t write the test shown below using FEST-Assert.


@Test
public void shouldContainAllElementsStartingWithavAndEndingWithe() {
assertThat(words, everyItem(both(startsWith("av")).and(endsWith("e"))));
}

The FEST-Assert API

The FEST-Assert API, which provides a fluent interface for writing assertions, is very rich and easy to use. It has a similar feel to mocking frameworks such as jMock and EasyMock. To start using FEST, you need to either download it or add its dependency in your Maven POM file.



org.easytesting
fest-assert
1.3

FEST-Assert provides assertions for the following data types:

  • Object
  • String
  • Collection
  • Map
  • Primitives (boolean, int, char, etc.)
  • Arrays of Object
  • Arrays of primitives
  • BufferedImage
  • Throwable
  • File
  • BigDecimal

Let’s rewrite some of the test cases from earlier in the article using matchers with FEST-Assert.


public class FESTAssertTest {

private List words;

@Before
public void setUp() {
words = Arrays.asList("available", "avenge", "avenue", "average");
}

@Test
public void shouldMatchACollectionContainingAElement() {
assertThat(words).isNotEmpty();
assertThat(words).hasSize(4);
assertThat(words).isNotNull();
assertThat(words).contains("available");
assertThat(words).hasSize(4).isNotEmpty();
}

@Test
public void compareTwoArrays(){
String[] s1 = {"a", "b"};
String[] s2 = {"a", "b"};
assertThat(s1).isEqualTo(s2);
}

@Test
public void testAShouldNotBeEqualToB(){
assertThat("A").isNotEqualTo("B");
}

@Test
public void shouldMatchCollectionContainingMultipleItems_FEST() {
assertThat(words).contains("available", "avenge", "avenue");
}

@Test
public void testFestAssertionLibrary(){
assertThat(0).isZero();
TeamMate shekhar = new TeamMate("shekhar", "gulati",26);
TeamMate rahul = new TeamMate("rahul", "sharma",27);
TeamMate sameer = new TeamMate("sameer", "arora",28);
List team = Arrays.asList(shekhar, rahul, sameer);

assertThat(team).contains(new TeamMate("shekhar", "gulati"));
assertThat(team).onProperty("firstName").contains("shekhar");
assertThat(team).isNotEmpty();
assertThat(team).hasSize(3).contains(shekhar,rahul,sameer);
assertThat(team.get(0)).isInstanceOf(TeamMate.class).isEqualTo(shekhar).isNotEqualTo(rahul);

}
}
Quick Tip for Eclipse Users: If you are using Eclipse you can use to shortcut Ctrl+Shift+M (Add Import) to statically import a method. You can also add static members to Java / Editor / Content Assist / Favorites that allow code completion on static methods.

Conclusion

Both Hamcrest and FEST-Assert do a great job of improving Java test readability and maintainability, but each has some limitations. I personally use both of them in my project to get the full power of both. Try them out and write more productive unit tests.

About the Author

Shekhar Gulati is a Java consultant with over 5 years of experience. He is currently working with Xebia India, an Agile software development company. He writes his personal blog at whyjava.wordpress.com.





Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel