Skip to main content

Junit 4.11 cheatsheet


Assertion - org.junit.Assert

  1. Equals, NotEquals, True, False, Null, NotNull - Arrays, Object & Strings

Test Aggregation

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestFeatureLogin.class,
  TestFeatureLogout.class,
  TestFeatureNavigate.class,
  TestFeatureUpdate.class
})

public class FeatureTestSuite {
  // the class remains empty,
  // used only as a holder for the above annotations
}

Exception Testing

  @Test(expected= IndexOutOfBoundsException.class) 
  public void empty() { 
       new ArrayList<Object>().get(0); 
  }
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
        List list = new ArrayList();

        thrown.expect(IndexOutOfBoundsException.class);
        thrown.expectMessage("Index: 0, Size: 0");
        list.get(0); // execution will never get past this line
    }

Matchers and assertthat

assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(responseString, either(containsString("color")).or(containsString("colour")));
assertThat(myList, hasItem("3"));

Ignoring tests


@Ignore("Test is ignored as a demonstration")
@Test
public void testSane() {
    assertThat(1, is(1));
}

Timeout for tests

@Test(timeout=1000)
public void testWithTimeout() {
  ...
}
public class HasGlobalTimeout {
    public static String log;

    @Rule
    public Timeout globalTimeout = new Timeout(10000); // 10 seconds max per method tested

    @Test
    public void testInfiniteLoop1() {
        log += "ran1";
        for (;;) {
        }
    }

    @Test
    public void testInfiniteLoop2() {
        log += "ran2";
        for (;;) {
        }
    }
}

Java code can be difficult to test for thread safety when multithreading.
The article at http://www.planetgeek.ch/2009/08/25/how-to-find-a-concurrency-bug-with-java/ describes a method of exposing concurrency bugs that adds a new assertion method assertConcurrent.
To use this you pass in a Collection of Runnables that are your arrange\act\assert test on the SUT, they all run at the same time in theassertConcurrent method; the chances of triggering a multithreading code error, and thereby failing some assertion are greatly increased:
The assertConcurrent method from the article is:
 public static void assertConcurrent(final String message, final List extends Runnable> runnables, final int maxTimeoutSeconds) throws InterruptedException {
   final int numThreads = runnables.size();
   final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>());
   final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
   try {
  final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
  final CountDownLatch afterInitBlocker = new CountDownLatch(1);
  final CountDownLatch allDone = new CountDownLatch(numThreads);
  for (final Runnable submittedTestRunnable : runnables) {
    threadPool.submit(new Runnable() {
   public void run() {
     allExecutorThreadsReady.countDown();
     try {
    afterInitBlocker.await();
    submittedTestRunnable.run();
     } catch (final Throwable e) {
    exceptions.add(e);
     } finally {
    allDone.countDown();
     }
   }
    });
  }
  // wait until all threads are ready
  assertTrue("Timeout initializing threads! Perform long lasting initializations before passing runnables to assertConcurrent", allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS));
  // start all test runners
  afterInitBlocker.countDown();
  assertTrue(message +" timeout! More than" + maxTimeoutSeconds + "seconds", allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS));
   } finally {
  threadPool.shutdownNow();
   }
   assertTrue(message + "failed with exception(s)" + exceptions, exceptions.isEmpty());
 }
Another article giving an overview of alternative stragies at http://tempusfugitlibrary.org/recipes/2012/05/20/testing-concurrent-code/ might also be useful.

Java Concurrency Bookshelf

Comments

Popular posts from this blog

Access multiple Databases in JPA

According to JPA specification we can define multiple "persistence-unit" elements (i.e. like below) in persistence.xml file and can easily refer them inside Dao layers as this. public class PolarDaoImpl {     @PersistenceContext(unitName="PolarPU")     protected EntityManager entityManager; -- } public class BearDaoImpl {     @PersistenceContext(unitName="BearPU")     protected EntityManager entityManager; -- } Checkout sample persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">     <!-- Database 1 -->     <persistence-unit name="PolarPU" transaction-type="RESOURCE_LOCAL">         <

JPA 2 new feature @ElementCollection explained

@ElementCollection is new annotation introduced in JPA 2.0, This will help us get rid of One-Many and Many-One shitty syntax. Example 1: Stores list of Strings in an Entity @Entity public class Users implements Serializable {     private static final long serialVersionUID = 1L;     @Id     @GeneratedValue(strategy = GenerationType.AUTO)     private Long id;     @ElementCollection     private List<String> certifications = new ArrayList <String> ();     public Long getId() {         return id;     }     public void setId(Long id) {         this.id = id;     }     public List <String> getCertifications() {         return certifications;     }     public void setCertifications(List <String> certifications) {         this.certifications = certifications;     } .. }         Users u = new Users();         u.getCertifications().add("Sun Certified Java Programmer");         em.persist(u); Generated Tables    Users    Co

Reuse JPA Entities as DTO

Note : Major design advantages of JPA Entities are they can detached and used across tiers and networks and later can by merged. Checkout this new way of querying entities in JPA 2.0 String ql = " SELECT new prepclass2.Employee (e.firstname, e.lastname) FROM Employee e "; List<Employee> dtos = em.createQuery(ql).getResultList(); The above query loads all Employee entities but with subset of data i.e. firstname, lastname. Employee entity looks like this. @Entity @Table(name="emp") public class Employee implements Serializable {     private static final long serialVersionUID = 1L;     @Id     @GeneratedValue(strategy = GenerationType.AUTO)     private Long id;     @Column     private String firstname;     @Column     private String lastname;     @Column     private String username;     @Column     private String street;     @Column     private String city;     @Column     private String state;     @Column     private String zipc