Skip to content

mmichaelis/hamcrest-nextdeed

Repository files navigation

Hamcrest — Next Deed

[Home] [Building] [Releasing] [Javadoc] [License]

Circle CI Maven Central Coverage Status Dependency Status Project Status Apache License, Version 2.0 Java Version

I am a fan of Hamcrest and its logo which actually emphasizes the clever wordplay. I like the ease of use of Hamcrest, its easy extensibility and its great approach of creating failure reports which sometimes do not even require to set an assertion message.

Hamcrest — Next Deed is an extension to Hamcrest and especially its library for even more matchers you may find useful.

The first version of Hamcrest — Next Deed was dedicated to a strategy to wait for the expected value for a certain amount of time and was inspired by an algorithm used successfully for several years now at CoreMedia especially but not only for UI tests. The pattern has shown that it is quite common, especially for any integration test, that you might have to wait and that you might to take some surprises into account as mentioned in the blog post Haste makes waste.

[Top]

Available Matchers

[Top]

Probe — Waiting For State

Probe is the result of the wait pattern adopted for general use with Hamcrest. A typical example looks like this:

Probe.<System, State>probing(system)
     .withinMs(1L)
     .assertThat(
         new Function<System, State>() {
           @Override
           public State apply(System input) {
             return input.getState();
           }
         },
         equalTo(State.RUNNING)
     );

The algorithm ensures that the system has enough time to actually reach this state.

The API makes use of Guava: Google Core Libraries for Java to make Java 8 features (functions, predicates, etc.) already available for Java 7.

[Top]

Applying Matcher — Transform Before Comparison

A simpler approach than waiting is that you have an object to run assertions on where you have no matcher at hand. For example – as above – the state of a system. The example above using the applying matcher which does not wait:

assertThat(system,
           applying(
               new Function<System, State>() {
                 @Override
                 public State apply(System input) {
                   return input.getState();
                 }
               },
               equalTo(State.RUNNING)
           )
);

In this example it is a little bit of overhead as you might directly do the assertion on system.getState(). You still might find this one useful as in this example:

expectedException.expectCause(allOf(
    Matchers.<Throwable>instanceOf(AssertionError.class),
    applying((input) -> input.getMessage(),
             allOf(
                 containsString("lorem"),
                 containsString("ipsum")
             ))
));

[Top]

Reflection Matchers

The following shows some of the reflection matchers which might be used to validate code style for utility classes – and in the same run ensures some more code coverage:

@Test
public void probeIsUtilityClass() throws Exception {
  errorCollector.checkThat("Class must be final.",
                           Probe.class,
                           classModifierContains(Modifier.FINAL));
  errorCollector.checkThat("Any constructors must be private.",
                           asList(Probe.class.getDeclaredConstructors()),
                           everyItem(memberModifierContains(Modifier.PRIVATE)));
  assertThat("Default constructor must exist.",
             Probe.class,
             isInstantiableViaDefaultConstructor());
}

[Top]

Side Note

Hamcrest — Next Deed is just another wordplay (if clever or not is up to you). Do you get the meaning?

[Top]

References

[Top]

Bookmarks

[Home] [Building] [Releasing] [Javadoc] [License] [Top]