Test Behaviour, Not Methods

JUnit4 introduced @Test annotations and removes the need to prefix test method names with ‘test’. Take advantage of this and use a different test case naming convention to test the class behaviour, not it’s implementation 
Compare the two units test below and see which one is easier to read. 
Think about diagnosing a test failure and also how quickly you can understand the what the code does. 

public class ShoppingCartTest {
 private ShoppingCart cart = null;

 @Before
 public void init() {
 cart = new ShoppingCart();
 cart.addItem( new
 ShoppingCart.Item( "Chocolate bar", 52 ) );
 }

 @Test
 public void testProcessPayment() {
 assertTrue( cart.processPayment( new CashPayment() ) );
 assertTrue( cart.processPayment( new VoucherPayment( "123" ) ) );
 assertFalse( cart.processPayment( new VoucherPayment( null ) ) );
 assertFalse( cart.processPayment( new VoucherPayment( "" ) ) );
 }
}

This test suite tests the expected behaviour and uses descriptive test names. Each test sticks to a single concept. This is also a great example of Unit Tests as documentation, each test case tells a story of what the code does.

public class ShoppingCartTest {
 private ShoppingCart cart = null;
 @Before
 public void init() {
 cart = new ShoppingCart();
 cart.addItem( new ShoppingCart.Item( "Chocolate bar", 52 ) );
 }

 @Test
 public void shouldProcessCashPayment() {
 assertTrue( cart.processPayment( new CashPayment() ) );
 }

 @Test
 public void shouldProcessVoucherPayment() {
 assertTrue( cart.processPayment( new VoucherPayment( "123" ) ) );
 }

 @Test
 public void shouldNotProcessVoucherPaymentForInvalidVoucherReference()
 {
 assertFalse( cart.processPayment( new VoucherPayment( null ) ) );
 assertFalse( cart.processPayment( new VoucherPayment( "" ) ) );
 }
}

Summary

  • Try to stick with one assert or a single concept per test case
  • Tests are much easier to read and maintain
  • It’s clear what has broken when a test fails
  • Refactoring of production code should not require any changes to test code Good test names are a way of documenting the code for free
  • TDD enforces test cases like the example on the right hand side, forcing you to think about the class behaviour in advance of coding it