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
AbstractKeyValueConverter
supports 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.
MultiPropertyMatcher
supports description contexts, where description providers are informed about object that is a subject of testing.
- More flexible initialization of files in
WorkFolder
, usingInitialContentProvider
interface. Useful utility providers (such aslines()
,bytes()
andserializedForm()
) are prepared inContentProviders
class. WorkFolder
can 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:
WorkFolder
did not create correct subfolder structure.
- Extracted
AbstractKeyValueConverter
that does not implementConverter
interface so that class signatures do not clash
- Parameter converter
KeyValueBeanAnnotationConverter
can become a base for specialized annotation converters
- Parameter annotation
@KeyValueBean
facilitates creation and initialization of simple beans. The parameter text should be a whitespace-separated list ofkey=value
pairs; the keys are then interpreted either as property names (in JavaBean sense) or as field names. @KeyValueBean
supports 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
@KeyValueBean
delegate setter, the property value argument can be aString
instance – in this case the delegate setter is responsible for appropriate parsing and conversion. - Property editors for
BigDecimal
andBigInteger
added (registered either directly or viaAdditionalPropertyEditors.register()
)
ArrayPartMatcher
implemented
- (Bug) Incorrect handling of parameter annotation
@BigInt
fixed
- File handling interface
WorkFolderInterface
provided forWorkFolder
as well as for its subfolders. FileMatchers
can match file attributes, using a new matcherFileFlagMatcher
- Functionality of
MultiPropertyMatcher
improved to simplify an instance construction
- To simplify creation of dedicated multi-property matchers that tend to follow a common pattern,
MultiPropertyMatcher
class was added - Natural list joining facility
NaturalDescriptionJoiner
added support for functional description generation; in Java 8, lambda construction can be efficiently used.
- Natural list joining facility
NaturalDescriptionJoiner
has better support for Hamcrest-related activities: descriptions of matchers' mismatches can be added to the result list (items where the matcher is eithernull
or matches the provided value are omitted from the result).
- Parameter annotation
@HexBuffer
can optionally specify desired buffer capacity as well as whether to skip the rewinding of the producedByteBuffer
- Parameter annotation
@HexArray
can optionally specify desired size of produced byte array - New matchers targetting
ByteBuffer
s were added - Parameter annotations
@BigDec
and@BigInt
can producenull
values from the text source, using appropriate annotation argument ByteSequenceFormatSupport
allows to format byte sequences into a readable form, typically into hexadecimal chunks- Added utility class
NaturalDescriptionJoiner
that facilitates construction of natural language item lists
- Support for JUnitParams "metaconversion"
- Annotation
@UsingPropertyEditor
will delegate parameter conversion to an appropriate JavaBeansPropertyEditor
implementation - 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
ArrayDimensionMatcher
with matcher factory methods for checking array dimensions- JUnitParams annotations
@MultiArray
and@MultiArrayInt
facilitating easy generation of multidimensional arrays as unit test's arguments.@MultiArray
can 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
@LogFramework
in a test class - Test rule
@LogBuffer
facilitates filtering and collection of log messages stored ascz.auderis.test.logging.LogRecord
instances - Hamcrest matchers for
LogRecord
allow detailed inspection of captured log output
- Support for JUnitParams 1.0.5 annotation-based converters
@BigDec
forjava.math.BigDecimal
objects@BigInt
forjava.math.BigInteger
objects@DateParam
and@CalendarParam
for legacy temporal classesjava.util.Date
andjava.util.Calendar
@HexArray
and@HexBuffer
for arbitrary byte sequences, producingbyte[]
andjava.nio.ByteBuffer
objects, respectively@XmlText
wraps text intojavax.xml.transform.Source
for further XML processing- Utility converter
@Guid
for 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
@MultiArray
JavaDoc 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 )));
}
}