Skip to content

Instantly share code, notes, and snippets.

@gkhays
Last active July 13, 2017 13:58
Show Gist options
  • Save gkhays/213e7e380b9f74c96f24 to your computer and use it in GitHub Desktop.
Save gkhays/213e7e380b9f74c96f24 to your computer and use it in GitHub Desktop.
Some new JUnit tricks...

How Many Assertions Per Unit Test

There is a really good exchange on Programmers Stack Exchange on the number of assertions to have in a single unit test: Is it OK to have multiple asserts in a single unit test?

Proper unit tests should fail for exactly one reason, that's why you should be using one assert per unit test.

More Assertions for JUnit

The "match at least one" example below relies on Hamcrest matchers. There is an alternative to Hamcrest, see AssertJ documentation.

  @Test
  public void testMatchThisOrThat() {
    // What if the result is either one or two?
    // Gotcha' covered! :)
    // Remember to import static org.hamcrest.CoreMatchers.* so the matchers come into scope.
    assertThat(dataType, anyOf(is("one"), is("two")));
  }

In this next case, I had an array of values where one or more elements should be matched. The Hamcrest IsIn matcher seems like a good fit, e.g.

@Test
public void testMatchIsIn() {
  // The result should be one of an array value.
  assertThat(dataType, isIn(new String[]{"one","two","three"}));
}

Note: This requires the Hamcrest library.

<dependency>
	<groupId>org.hamcrest</groupId>
	<artifactId>hamcrest-library</artifactId>
	<version>1.3</version>
</dependency>

Exception Testing

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

Deeper Exception Testing

@Test
public void testExceptionMessage() {
    try {
        new ArrayList<Object>().get(0);
        fail("Expected an IndexOutOfBoundsException to be thrown");
    } catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
        assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
    }
}

See Expected Exceptions.

import static org.hamcrest.collection.IsIn.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
/**
* Some new assertions for JUnit.
*/
public class MatchAtLeastOneOf {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
// https://stackoverflow.com/questions/4667903/checking-for-2-expected-values-in-junit
@Test(expected=NullPointerException.class)
public void testCatchExpectedException() {
theMethod();
}
@Test
public void testCatchWithTryCatch() {
try {
theMethod();
fail("I was expecting a different exception");
} catch (NullPointerException e) {
// Success!
}
}
// Ignore this test for now.
@Ignore("Why?")
@Test
public void testIgnoringThisOne() {
}
// Uses the Hamcrest CoreMatcher.
// https://stackoverflow.com/questions/6028750/how-to-assert-an-actual-value-against-2-or-more-expected-values
// https://github.com/junit-team/junit/wiki/Matchers-and-assertthat
// https://code.google.com/archive/p/hamcrest/wikis/Tutorial.wiki
@Test
public void testMatchThisOrThat() {
// What if the result is either one or two?
// Gotcha' covered! :)
// Remember to import static org.hamcrest.CoreMatchers.* so the matchers come into scope.
assertThat(dataType, anyOf(is("one"), is("two")));
}
@Test
public void testIsInTheArray() {
assertThat(dataType, isIn(new String[]{"one","two","three"}));
}
// TODO - I came across a question where the poster wanted to test System.out.
// JUnit test for System.out.println()
// https://stackoverflow.com/questions/1119385/junit-test-for-system-out-println
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
@Before
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
}
@After
public void cleanUpStreams() {
System.setOut(null);
System.setErr(null);
}
@Test
public void out() {
System.out.print("hello");
assertEquals("hello", outContent.toString());
}
@Test
public void err() {
System.err.print("hello again");
assertEquals("hello again", errContent.toString());
}
// Additional References:
// https://stackoverflow.com/questions/12729280/junit-how-to-check-if-string-is-equal-to-one-of-two-strings
// https://stackoverflow.com/questions/18766235/how-to-assert-greater-than-using-junit-assert
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment