我编写了一个自定义Junit运行程序来控制如何运行参数化测试。以下是它的源代码。
问题是现在从它扩展的类不支持Assume.assumeTrue(someFalseCondition)。它不会被忽略,而是会失败,例如
org.junit.internal.AssumptionViolatedException: got: <false>, expected: is <true>
at org.junit.Assume.assumeThat(Assume.java:70)
at org.junit.Assume.assumeTrue(Assume.java:39)
at org.terracotta.tests.base.AbstractTestBase.setUp(AbstractTestBase.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
下面这节课中我有什么遗漏。
public class TcTestRunner extends Suite {
/**
* Annotation for a method which provides parameters to be injected into the test class constructor by
* <code>Parameterized</code>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Configs {
// Empty Annotation
}
private class TestClassRunnerForParameters extends BlockJUnit4ClassRunner {
private final int fParameterSetNumber;
private final List<TestConfig> fParameterList;
TestClassRunnerForParameters(Class<?> type, List<TestConfig> parameterList, int i) throws InitializationError {
super(type);
fParameterList = parameterList;
fParameterSetNumber = i;
}
@Override
public Object createTest() throws Exception {
return getTestClass().getOnlyConstructor().newInstance(computeParams());
}
private TestConfig computeParams() throws Exception {
try {
return fParameterList.get(fParameterSetNumber);
} catch (ClassCastException e) {
throw new Exception(String.format("%s.%s() must return a Collection of arrays.", getTestClass().getName(),
getParametersMethod(getTestClass()).getName()));
}
}
@Override
protected String getName() {
return String.format(fParameterList.get(fParameterSetNumber).getConfigName());
}
@Override
protected String testName(final FrameworkMethod method) {
return String.format("%s[%s]", method.getName(), fParameterList.get(fParameterSetNumber).getConfigName());
}
@Override
protected void validateConstructor(List<Throwable> errors) {
validateOnlyOneConstructor(errors);
}
@Override
protected Statement classBlock(RunNotifier notifier) {
return childrenInvoker(notifier);
}
}
private final ArrayList<Runner> runners = new ArrayList<Runner>();
/**
* Only called reflectively. Do not use programmatically.
*/
public TcTestRunner(Class<?> klass) throws Throwable {
super(klass, Collections.<Runner> emptyList());
List<TestConfig> parametersList = getParametersList(getTestClass());
for (int i = 0; i < parametersList.size(); i++)
runners.add(new TestClassRunnerForParameters(getTestClass().getJavaClass(), parametersList, i));
}
@Override
protected List<Runner> getChildren() {
return runners;
}
@SuppressWarnings("unchecked")
private List<TestConfig> getParametersList(TestClass klass) throws Throwable {
return (List<TestConfig>) getParametersMethod(klass).invokeExplosively(null);
}
private FrameworkMethod getParametersMethod(TestClass testClass) throws Exception {
List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Configs.class);
for (FrameworkMethod each : methods) {
int modifiers = each.getMethod().getModifiers();
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) return each;
}
throw new Exception("No public static parameters method on class " + testClass.getName());
}
}