Testing Utilities
A collection of testing utilities for Java projects, providing fake
concurrency primitives (clocks, executors), console I/O capture, classpath
resource helpers, Kubernetes ConfigMap simulation, and random text generation.
Includes dedicated integration modules for both JUnit 4 and JUnit 5 with
annotation-driven configuration and parameter injection.
See morimekta.net/utils for procedures on releases.
Getting Started
To add to maven: Add this line to pom.xml under dependencies:
<dependencies>
<dependency>
<groupId>net.morimekta.utils</groupId>
<artifactId>testing</artifactId>
<version>5.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.morimekta.utils</groupId>
<artifactId>testing-junit4</artifactId>
<version>5.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.morimekta.utils</groupId>
<artifactId>testing-junit5</artifactId>
<version>5.6.1</version>
<scope>test</scope>
</dependency>
</dependencies>
To add to gradle: Add this line to the dependencies group in build.gradle:
testImplementation 'net.morimekta.utils:testing:5.6.1'
testImplementation 'net.morimekta.utils:testing-junit4:5.6.1'
testImplementation 'net.morimekta.utils:testing-junit5:5.6.1'
Testing
General testing utilities.
Concurrency Utils
FakeClock: A fake implementation ofjava.time.Clockthat holds time constant until explicitly advanced viatick(). Listeners can be registered to be notified when time progresses, making it easy to test time-dependent code deterministically without real delays.
java
FakeClock clock = FakeClock.forCurrentTimeMillis(1234567890_000L);
clock.addListener(newInstant -> System.out.println("Time: " + newInstant));
clock.tick(Duration.ofSeconds(5));
FakeScheduledExecutor: AScheduledExecutorServicethat uses aFakeClockas its time source and executes tasks in a real background thread pool. Tasks are triggered when the fake clock is ticked, giving you control over when scheduled work runs while still exercising real concurrency.
```java FakeClock clock = new FakeClock(); FakeScheduledExecutor executor = new FakeScheduledExecutor(clock);
Future
clock.tick(100); Thread.sleep(10); // let background thread complete assertThat(future.get(), is("done")); executor.shutdown(); ```
ImmediateExecutor: AnExecutorServicethat runs all submitted tasks synchronously in the calling thread. The task completes beforesubmit()returns, so the returned future is always already done. Useful for removing threading complexity from unit tests.
java
ImmediateExecutor executor = new ImmediateExecutor();
Future<String> future = executor.submit(() -> "immediate");
assertThat(future.isDone(), is(true));
assertThat(future.get(), is("immediate"));
ImmediateScheduledExecutor: AScheduledExecutorServicethat uses aFakeClockfor scheduling and runs tasks synchronously in the thread that triggers the clock tick. UnlikeFakeScheduledExecutor, no background threads are involved, making tests fully deterministic and single-threaded.
```java FakeClock clock = new FakeClock(); ImmediateScheduledExecutor executor = new ImmediateScheduledExecutor(clock);
AtomicInteger counter = new AtomicInteger(0); executor.scheduleAtFixedRate(counter::incrementAndGet, 0, 100, MILLISECONDS);
clock.tick(100); assertThat(counter.get(), is(1)); clock.tick(200); assertThat(counter.get(), is(3)); ```
Console Utils
Console: An interface for controlling and inspecting console I/O during testing. Provides access to a fake TTY and captured stdout/stderr content, and allows setting stdin programmatically.
java
console.setInput("yes\n");
System.out.println("Hello");
assertThat(console.output(), is("Hello\n"));
ConsoleManager: Base class that hijacksSystem.in,System.out, andSystem.errwith fake implementations for the duration of a test. Captured output can be inspected via theConsoleinterface, and the original streams are restored after each test. Supports dumping captured output on test failure for easier debugging.
I/O and File Utils
ResourceUtil: Utility class for loading classpath resources in tests. Can copy a resource to a filesystem path or read its content as a string, using the calling class as the resource loading context.
java
Path file = ResourceUtil.copyResourceTo("/schema.sql", tempDir);
String content = ResourceUtil.resourceAsString("/test-data.json");
TestConfigMap: Wraps a directory to simulate a Kubernetes ConfigMap volume mount for testing. Manages versioned snapshots with symbolic links and supports atomic updates via a try-with-resources transaction, just like a real ConfigMap mount.
java
TestConfigMap config = new TestConfigMap(tempDir);
try (var update = config.update()) {
update.copyResource("/default-config.txt");
update.writeContent("custom.txt", "value");
}
assertThat(config.getPath("custom.txt"), exists());
Text Utils
EnglishWords: A lightweight random text generator for producing dummy test data. Generates random English words, sentences, paragraphs, and standard Lorem Ipsum text using a simple subject-verb-object sentence pattern.
java
String word = EnglishWords.word(); // e.g. "dog"
String sentence = EnglishWords.sentence(50); // at least 50 chars
String para = EnglishWords.paragraph(3); // 3 sentences
String lorem = EnglishWords.loremIpsum();
JUnit 4
Utilities specialized for JUnit 4.
ConsoleWatcher: A JUnit 4TestWatcher@Rulethat sets up a fake console before each test and restores the original system streams afterward. Provides fluent configuration for terminal size, interactivity, and dumping output on test failure.
```java @Rule public ConsoleWatcher console = new ConsoleWatcher() .withTerminalSize(20, 80) .interactive() .dumpOnFailure();
@Test public void testOutput() { System.out.println("Hello"); assertThat(console.console().output(), containsString("Hello")); } ```
DataProviderUtil: Utility forcom.tngtech.java:junit-dataproviderthat generates the Cartesian product of multiple parameter dimensions. Pass in lists of values for each dimension and get back a 2D array of all combinations, simplifying parameterized test setup.
java
@DataProvider
public static Object[][] testParams() {
return DataProviderUtil.buildDataDimensions(
List.of(ContentType.WALLPAPER, ContentType.AUDIO),
List.of(Locale.US, Locale.DE)
);
// Produces: [WALLPAPER,US], [WALLPAPER,DE], [AUDIO,US], [AUDIO,DE]
}
JUnit 5
Utilities specialized for JUnit 5.
ConsoleExtension: A JUnit 5 extension that provides fake console I/O with parameter injection support. InjectsConsoleorTTYdirectly into test method parameters, and supports annotations like@ConsoleSize,@ConsoleInteractive, and@ConsoleDumpOutputOnFailurefor configuration.
java
@ExtendWith(ConsoleExtension.class)
@ConsoleSize(rows = 20, cols = 80)
@ConsoleInteractive
public class MyTest {
@Test
public void testOutput(Console console) {
System.out.println("Hello");
assertThat(console.output(), containsString("Hello"));
}
}
ParamsProviderUtil: Utility for JUnit 5@ParameterizedTestwith@MethodSourcethat generates the Cartesian product of parameter dimensions. Transforms multipleArgumentsobjects into aStream<Arguments>of all combinations.
```java
public static Stream
@ParameterizedTest @MethodSource("params") public void test(ContentType type, Locale locale) { ... } ```
DataSourceExtension: A JUnit 5 extension that manages a JDBCDataSourcefor database testing. Creates an in-memory H2 database by default and supports parameter injection ofJdbi,DataSource, or the connection URI string. Use annotations like@DataSourceMode,@DataSourceSchema, and@DataSourceDriverClassto configure the database engine and initial schema.
java
@ExtendWith(DataSourceExtension.class)
@DataSourceMode(DataSourceMode.Mode.POSTGRESQL)
public class MyDatabaseTest {
@Test
@DataSourceSchema("/schema.sql")
public void testQuery(Jdbi jdbi) {
var db = jdbi.onDemand(MyDBI.class);
assertThat(db.queryUsers(), is(notNullValue()));
}
}
Major Version Changes
4.x->5.x: FakeScheduledExecutor renamed ImmediateScheduledExecutor and new FakeScheduledExecutor created using a real background executor, but using the fake clock to trigger the scheduled tasks.