AssertJ

JUnit is the most popular framework for unit testing. To check or assert any variable, it provides these methods:

public static void assertTrue(boolean condition)
public static void assertFalse(boolean condition)
public static void assertEquals(Object expected, Object actual)
...

These methods are enough for unit testing. However, I’ve noticed that a assertion message is not descriptive. Here is an example.

1
2
3
4
5
@Test
public void testEnabledAfterDisabled() throws Exception {
  mUnderTest.setEnabled(false);
  assertFalse(mUnderTest.isEnabled());
}

In this unit test, checking the status after disabling it. When assertFalse is failed, an assertion exception occurs and you can see the message like below.

java.lang.AssertionError
	at org.junit.Assert.fail(Assert.java:86)
	at org.junit.Assert.assertTrue(Assert.java:41)
	at org.junit.Assert.assertTrue(Assert.java:52)
	at test.TextViewTest.java:10)

As you see, the message is not descriptive. It only shows that there is an assertion error. If you want to check it, you need to go to the source code. Furthermore, you need to think the expected value and actual value. Since the assertion method was assertFalse, expected value was false but actual value was true. For me, this is a quite annoying process since I need to check the source and think the expected and actual value.

I’ve found that there is a handy library for this, which is called AssertJ. Here is an example with AssertJ.

1
2
3
4
5
@Test
public void testEnabledAfterDisabled() throws Exception {
  mUnderTest.setEnabled(false);
  assertThat(mUnderTest.isEnabled()).isFalse();
}

The main change is to use assertThat instead of assertFalse. Now, you can see more descriptive message when an assertion error occurs.

org.junit.ComparisonFailure:
Expected :true
Actual   :false
 <Click to see difference>
	at test.TextViewTest.java:10)

In addition, AssertJ supports fluent APIs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron)
                 .isIn(fellowshipOfTheRing);

// String specific assertions
assertThat(frodo.getName()).startsWith("Fro")
                           .endsWith("do")
                           .isEqualToIgnoringCase("frodo");

// collection specific assertions
assertThat(fellowshipOfTheRing).hasSize(9)
                               .contains(frodo, sam)
                               .doesNotContain(sauron);

If you want to how to setup AssertJ and use it, please check http://joel-costigliola.github.io/assertj/.

AssertJ can be used for Android unit testing, but with AssertJ Android http://square.github.io/assertj-android/, test code can be more concise.

1
2
3
4
5
6
7
8
9
10
11
// Regular AssertJ
assertThat(layout.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(layout.getOrientation()).isEqualTo(VERTICAL);
assertThat(layout.getChildCount()).isEqualTo(4);
assertThat(layout.getShowDividers()).isEqualTo(SHOW_DIVIDERS_MIDDLE);

// AssertJ Android
assertThat(layout).isVisible()
    .isVertical()
    .hasChildCount(4)
    .hasShowDividers(SHOW_DIVIDERS_MIDDLE);