Skip to content

Instantly share code, notes, and snippets.

@nipafx
Created May 21, 2017 12:17
Show Gist options
  • Save nipafx/b1ebad57dbb0a15a32283e9b741ec437 to your computer and use it in GitHub Desktop.
Save nipafx/b1ebad57dbb0a15a32283e9b741ec437 to your computer and use it in GitHub Desktop.
Injecting random data into Jupiter tests
import org.codefx.demo.junit5.extensions.RandomParameterExtensionTest.RandomProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler;
import org.junit.jupiter.api.extension.TestExtensionContext;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
@ExtendWith(RandomProvider.class)
class RandomParameterExtensionTest {
@BeforeAll
static void beforeAll_1(SeededRandom r) {
System.out.println("Before all #1: " + r.seed());
}
@BeforeAll
static void beforeAll_2(SeededRandom r) {
System.out.println("Before all #2: " + r.seed());
}
@BeforeEach
void beforeEach_1(SeededRandom r) {
System.out.println("Before each #1: " + r.seed());
}
@BeforeEach
void beforeEach_2(SeededRandom r) {
System.out.println("Before each #2: " + r.seed());
}
@Test
void test(SeededRandom r) {
System.out.println("Test: " + r.seed());
}
@Test
void failingTest(SeededRandom r) {
System.out.println("Failing Test: " + r.seed());
throw new IllegalArgumentException("FAIL!");
}
@AfterEach
void afterEach_1(SeededRandom r) {
System.out.println("After each #1: " + r.seed());
}
@AfterEach
void afterEach_2(SeededRandom r) {
System.out.println("After each #2: " + r.seed());
}
@AfterAll
static void afterAll_1(SeededRandom r) {
System.out.println("After all #1: " + r.seed());
}
@AfterAll
static void afterAll_2(SeededRandom r) {
System.out.println("After all #2: " + r.seed());
}
static class RandomProvider implements ParameterResolver, TestExecutionExceptionHandler {
private final Map<String, SeededRandom> randoms = new ConcurrentHashMap<>();
@Override
public boolean supports(
ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
Class<?> targetType = parameterContext.getParameter().getType();
return targetType == Random.class || targetType == SeededRandom.class;
}
@Override
public Object resolve(
ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
return randoms.computeIfAbsent(extensionContext.getUniqueId(), SeededRandom::create);
}
@Override
public void handleTestExecutionException(
TestExtensionContext context, Throwable throwable) throws Throwable {
String seed = Optional.ofNullable(randoms.get(context.getUniqueId()))
.map(SeededRandom::seed)
.map(s -> "seed " + s)
.orElse("unknown seed");
System.out.println("Exception occurred in test based on " + seed);
}
}
static class SeededRandom extends Random {
private static Random seeder = new Random();
private final String testId;
private final long seed;
private SeededRandom(String testId, long seed) {
super(seed);
this.testId = testId;
this.seed = seed;
}
static SeededRandom create(String testId) {
return new SeededRandom(testId, seeder.nextLong());
}
String testId() {
return testId;
}
long seed() {
return seed;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment