Useful additions to JUnit/Hamcrest/JUnitParams testing environment. You will reduce most of unit test boilerplate significantly:
- Test cases can receive parameters of various types, as complex as needed.
- Test assertions will be almost perfectly human-readable, providing natural constraints for tested objects
- Creation of additional object matchers is simplified by
MultiPropertyMatcher
As a result, many test cases shrink to a couple of lines of code (excluding parameter definition). Following the Given-When-Then (also known as "Arrange-Act-Assert") test style, you'll notice that Given section will be often empty and each of sections When, Then may consist of a single line of code.
Keywords: Unit tests, Hamcrest, JUnitParams
AbstractKeyValueConvertersupports additional methods how to set a property to a bean; if the property delegate class offers methodsetExtraProperty(bean, propertyName, textValue), it is used as one of fallback methods. Subclasses can provide their own property setting code.
MultiPropertyMatchersupports description contexts, where description providers are informed about object that is a subject of testing.
- More flexible initialization of files in
WorkFolder, usingInitialContentProviderinterface. Useful utility providers (such aslines(),bytes()andserializedForm()) are prepared inContentProvidersclass. WorkFoldercan provide a ClassLoader that looks up resources within the work folder space. The classloader can be obtained viagetClassLoaderForResources(); when needed, it can be installed as current thread's context classloader by callinginstallContextClassLoaderForResources().
- Fix:
WorkFolderdid not create correct subfolder structure.
- Extracted
AbstractKeyValueConverterthat does not implementConverterinterface so that class signatures do not clash
- Parameter converter
KeyValueBeanAnnotationConvertercan become a base for specialized annotation converters
- Parameter annotation
@KeyValueBeanfacilitates creation and initialization of simple beans. The parameter text should be a whitespace-separated list ofkey=valuepairs; the keys are then interpreted either as property names (in JavaBean sense) or as field names. @KeyValueBeansupports so-called property delegates, where setters are looked-up in a different class. These "delegate setters" require two arguments – a target bean reference and the actual property value. The delegate setters can be static.- To facilitate special conversion needs when using a
@KeyValueBeandelegate setter, the property value argument can be aStringinstance – in this case the delegate setter is responsible for appropriate parsing and conversion. - Property editors for
BigDecimalandBigIntegeradded (registered either directly or viaAdditionalPropertyEditors.register())
ArrayPartMatcherimplemented
- (Bug) Incorrect handling of parameter annotation
@BigIntfixed
- File handling interface
WorkFolderInterfaceprovided forWorkFolderas well as for its subfolders. FileMatcherscan match file attributes, using a new matcherFileFlagMatcher
- Functionality of
MultiPropertyMatcherimproved to simplify an instance construction
- To simplify creation of dedicated multi-property matchers that tend to follow a common pattern,
MultiPropertyMatcherclass was added - Natural list joining facility
NaturalDescriptionJoineradded support for functional description generation; in Java 8, lambda construction can be efficiently used.
- Natural list joining facility
NaturalDescriptionJoinerhas better support for Hamcrest-related activities: descriptions of matchers' mismatches can be added to the result list (items where the matcher is eithernullor matches the provided value are omitted from the result).
- Parameter annotation
@HexBuffercan optionally specify desired buffer capacity as well as whether to skip the rewinding of the producedByteBuffer - Parameter annotation
@HexArraycan optionally specify desired size of produced byte array - New matchers targetting
ByteBuffers were added - Parameter annotations
@BigDecand@BigIntcan producenullvalues from the text source, using appropriate annotation argument ByteSequenceFormatSupportallows to format byte sequences into a readable form, typically into hexadecimal chunks- Added utility class
NaturalDescriptionJoinerthat facilitates construction of natural language item lists
- Support for JUnitParams "metaconversion"
- Annotation
@UsingPropertyEditorwill delegate parameter conversion to an appropriate JavaBeansPropertyEditorimplementation - A factory method can be used for String-to-Target conversion using annotation
@UsingFactory
- Annotation
- Build platform switched from Maven to Gradle
- Logging output testing extended
- Added support for Log4J 1.2.x
- Multiple logging frameworks can be captured at the same time (e.g. using
LogFramework.everything()) - When requested logging framework is not on classpath, its capturing is disabled
- Support for tests of multidimensional arrays
ArrayDimensionMatcherwith matcher factory methods for checking array dimensions- JUnitParams annotations
@MultiArrayand@MultiArrayIntfacilitating easy generation of multidimensional arrays as unit test's arguments.@MultiArraycan work with arbitrary array item types, including all primitive types and with support for selected built-in types (e.g.java.math.BigDecimal).
- Tools for testing logging output
- Normal output of a logging framework is redirected to memory buffer, preventing disk/network activity outside of the scope of unit tests
- Frameworks currently supported: SLF4J and JBoss Logging
- Logging framework intercepted by applying class rule
@LogFrameworkin a test class - Test rule
@LogBufferfacilitates filtering and collection of log messages stored ascz.auderis.test.logging.LogRecordinstances - Hamcrest matchers for
LogRecordallow detailed inspection of captured log output
- Support for JUnitParams 1.0.5 annotation-based converters
@BigDecforjava.math.BigDecimalobjects@BigIntforjava.math.BigIntegerobjects@DateParamand@CalendarParamfor legacy temporal classesjava.util.Dateandjava.util.Calendar@HexArrayand@HexBufferfor arbitrary byte sequences, producingbyte[]andjava.nio.ByteBufferobjects, respectively@XmlTextwraps text intojavax.xml.transform.Sourcefor further XML processing- Utility converter
@Guidfor UUID objects
- Additional Hamcrest matchers for text, date and raw array validation
- Hamcrest matchers for
java.math.BigDecimal- Matchers for numeric properties (scale, precision)
- Matchers working with rounded values
- Added various type converters for JUnitParams library.
public class LoggingTest {
@ClassRule
public static LogFramework logFramework = LogFramework.slf4j();
@Rule
public LogBuffer logBuffer = new LogBuffer();
@Test
public void testOfLogging() throws Exception {
// GIVEN
logBuffer.levels().enableOnly( LogLevel.INFO.plusHigherLevels() );
// WHEN
Logger log = LoggerFactory.getLogger("x");
log.info( "This is a log" );
// THEN
final List<LogRecord> infoRecords = logBuffer.getRecords();
assertThat( infoRecords, hasSize(1) );
final LogRecord logRecord = infoRecords.get(0);
assertThat( logRecord, hasLevel(LogLevel.INFO) );
assertThat( logRecord, hasMessage("This is a log") );
}
}The following tests demonstrate:
- Conversion of flat parameter lists into multidimensional arrays (see
@MultiArrayJavaDoc for details) - Usage of specialized Hamcrest matcher that checks multidimensional array dimensions
@RunWith(JUnitParamsRunner.class)
public class MultiDimTest {
@Test
@Parameters({
"2x2x2 : 1 2 -3 -4 -5 -6 7 8 | 2 * 2 * 2",
"3 : 9 8 7 | 3",
"4x0 : | 4 X 0"
})
public void testPrimitiveIntArray(@MultiArray(int.class) Object intArray, String expectedDimension) throws Exception {
assertThat( intArray, is( arrayWithDimensions( expectedDimension )));
}
@Test
@Parameters({
"2x1x2 : -5.009 -6.999 7.432 8.977131 | 2 * 1 * 2",
"3 : 9 8 7 | 3",
"4x0 : | 4 X 0"
})
public void testBigDecimalArray(@MultiArray(BigDecimal.class) Object bigDecArray, String expectedDimension) throws Exception {
assertThat( bigDecArray, is( arrayWithDimensions( expectedDimension )));
}
}