JUnit – assertThat (Hamcrest) – part 1

Hamcrest is a framework for creating matcher objects. These matcher objects are predicates and are used to write rules which can be satisfied under certain conditions. They are most often used in testing. Hamcrest lets us step beyond simple JUnit asserts and enables us to craft very specific and readable verification code. Hamcrest has the target to make tests as readable as possible. In general, the Hamcrest error messages are also much easier to read. Using Hamcrest matchers also provides more type safety as these matchers uses generics.

Simple Matchers

  • any()

  • anything()

  • arrayContaining()

Does the array contain all given items in the order in which they are input to the matcher?

  • arrayContainingInAnyOrder()

Does the array contain all the given items? Length of the array must match the number of matchers, but their order is not important.

  • arrayWithSize()

Does the input array have exactly the specified length?

  • closeTo()

Matcher which can be used with either Double or BigDecimal to check if a value is within a specified error margin of an expected value.

 

 

 

 

JUnit – basics introduction

The JUnit framework

JUnit (http://junit.org/) in version 4.x is a test framework which uses annotations to identify methods that specify a test.

A unit test is a fundamental test to quickly assess whether the result of a computation can possibly go wrong or not. It is a straightforward check to verify the basis of the computation result. To define a method as a unit test, you annotate it with the @org.junit.Test annotation. You use an assert method, provided by JUnit or another assert framework, to check an expected result versus the actual result.

Recommended practice

Generally, we don’t mix production code with the test code, so unit tests are kept in the same project, but under a different directory or source folder.

In widespread use is to use the name of the class under test and to add the “Test” suffix to the test class.

As a general rule, a test name should explain what the test does. If that is done correctly, it helps to avoid reading the actual implementation.

JUnit code constructs

JUnit 4.x uses annotations to mark methods as test methods and to configure them.

The @Test annotation signifies a test. We can annotate any public method with @Test to make it a JUnit test method.

JUnit 4 defines two method-level annotations, @BeforeClass and @AfterClass, for public static methods. Being static, they get executed only once per test class. Any public static method annotated with @BeforeClass gets executed prior to the first test, and any public static method annotated with @AfterClass gets executed following the last test.

Other mostly used JUnit annotations:

@Test (expected = Exception.class) – Fails if the method does not throw the named exception.

@Before – This method is executed before each test. It is used to prepare the test environment (e.g., read input data, initialize the class).

@After – This method is executed after each test. It is used to cleanup the test environment (e.g., delete temporary data, restore defaults).

@Ignore – Sometimes you want to temporarily disable a test or a group of tests. Methods annotated with @Test that are also annotated with @Ignore will not be executed as tests. Also, you can annotate a class containing test methods with @Ignore and none of the containing tests will be executed. It is best practice to provide the optional description, why the test is disabled.

And result is:

As you probably noticed tests execution order is different from the order of test methods.By design, JUnit does not specify the execution order of test method invocations. Well-written test code would not assume any order.

From version 4.11, JUnit will by default use a deterministic, but not predictable, order(MethodSorters.DEFAULT). To change the test execution order simply annotate your test class using @FixMethodOrder and specify one of the available MethodSorters:

@FixMethodOrder(MethodSorters.JVM): Leaves the test methods in the order returned by the JVM. This order may vary from run to run.

@FixMethodOrder(MethodSorters.NAME_ASCENDING): Sorts the test methods by method name, in lexicographic order.

Assert statements

Verifying an expectation with an assertion. JUnit provides static methods to test for certain conditions via the Assertclass. These assert statementstypically start with assert . They allow you to specify the error message, the expected and the actual result. An assertion method compares the actual value returned by a test to the expected value. It throws an AssertionExceptionif the comparison fails.

Mostly used assert methods:

fail(message) – Let the method fail. Might be used to check that a certain part of the code is not reached or to have a failing test before the test code is implemented. The message parameter is optional.

assertTrue([message,] boolean condition) – Asserts that a condition is true.

assertFalse([message,] boolean condition) – Asserts that a condition is false.

assertEquals([message,] expected, actual) – Asserts that two objects are equal. If they are not, an AssertionError is thrown with the given message. If expected and actual are null, they are considered equal. For arrays the reference is checked not the content of the arrays.

assertNull([message,] object) – Checks that the object is null.

assertNotNull([message,] object) – Checks that the object is not null.

assertSame([message,] expected, actual) – Checks that both variables refer to the same object.

assertNotSame([message,] expected, actual) – Checks that both variables refer to different objects.

Examining exception handling

In a JUnit test, when a test method throws an exception, the test fails, and the test method marks the test as erroneous. We should be allowed to unit test the exceptional condition such that an API takes two objects and throws an exception if any argument is passed as null . If we pass
a null value to the API, the test fails with an error, but actually, an exception is not an error. Rather, it is desirable, and the test should fail if the API doesn’t throw an exception.

JUnit 4 provides a mechanism to handle the preceding situation.
The @Test annotation takes an expected=<<Exception class name>>.class argument.
When we annotate a test method with @Test and pass an expected exception to the annotation, but during execution, the expected exception doesn’t match the real exception thrown from the test method or the test method doesn’t throw an exception, the test fails.

This exception handling mechanism doesn’t allow you to verify the error message. JUnit 4 provides several other mechanisms that are usually considered to be better solutions, such as @Rule , an ExpectedException rule that lets you examine the message as well as the type.

Test suits

A test suite groups and executes multiple tests. To run multiple tests together, we need a test suite. To achieve this, JUnit 4 offers the Suite.class class and the @Suite.SuiteClasses annotation. This annotation accepts a comma-separated array of test classes. Add a Java class named TestSuite and annotate it with @RunWith(Suite.class). As a result, the suite runner will be responsible for executing the test class. Annotate the TestSuite class with @Suite.SuiteClasses and pass a comma-separated array of other test classes, such as ({ ClientTest.class,
ClientOrder.class, ShoppingBasket.class }) .

When we execute the TestSuite class, it, in turn, executes all the test classes passed to the @Suite.SuiteClasses annotation.