另一种方法可能是使用新的 JUnit 5 - Jupiter 框架提供的设施。
我把我在 Eclipse Oxygen 上用 Java 1.8 测试过的代码放在下面。该代码缺乏优雅和简洁,但有望成为为您的元测试用例构建强大解决方案的基础。
请注意,这实际上是 JUnit 5 的测试方式,我建议您参考Github 上的 Jupiter 引擎的单元测试。
public final class DisallowUppercaseLetterAtBeginningTest {
@Test
void testIt() {
// Warning here: I checked the test container created below will
// execute on the same thread as used for this test. We should remain
// careful though, as the map used here is not thread-safe.
final Map<String, TestExecutionResult> events = new HashMap<>();
EngineExecutionListener listener = new EngineExecutionListener() {
@Override
public void executionFinished(TestDescriptor descriptor, TestExecutionResult result) {
if (descriptor.isTest()) {
events.put(descriptor.getDisplayName(), result);
}
// skip class and container reports
}
@Override
public void reportingEntryPublished(TestDescriptor testDescriptor, ReportEntry entry) {}
@Override
public void executionStarted(TestDescriptor testDescriptor) {}
@Override
public void executionSkipped(TestDescriptor testDescriptor, String reason) {}
@Override
public void dynamicTestRegistered(TestDescriptor testDescriptor) {}
};
// Build our test container and use Jupiter fluent API to launch our test. The following static imports are assumed:
//
// import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass
// import static org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder.request
JupiterTestEngine engine = new JupiterTestEngine();
LauncherDiscoveryRequest request = request().selectors(selectClass(MyTest.class)).build();
TestDescriptor td = engine.discover(request, UniqueId.forEngine(engine.getId()));
engine.execute(new ExecutionRequest(td, listener, request.getConfigurationParameters()));
// Bunch of verbose assertions, should be refactored and simplified in real code.
assertEquals(new HashSet<>(asList("validTest()", "TestShouldNotBeCalled()")), events.keySet());
assertEquals(Status.SUCCESSFUL, events.get("validTest()").getStatus());
assertEquals(Status.FAILED, events.get("TestShouldNotBeCalled()").getStatus());
Throwable t = events.get("TestShouldNotBeCalled()").getThrowable().get();
assertEquals(RuntimeException.class, t.getClass());
assertEquals("test method names should start with lowercase.", t.getMessage());
}
虽然有点冗长,但这种方法的一个优点是它不需要模拟和在同一个 JUnit 容器中执行测试,稍后将用于真正的单元测试。
通过一些清理,可以实现更具可读性的代码。同样,JUnit-Jupiter 资源可以成为很好的灵感来源。