gpt4 book ai didi

java - 在 Eclipse Testrunner 中具有名称的 ParameterizedTest

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:16:56 26 4
gpt4 key购买 nike

当您使用 Eclipse TestRunner 运行 JUnit 4 ParameterizedTest 时,图形表示相当笨拙:对于每个测试,您都有一个名为 [0][1] 等是否可以给测试 [0][1] 等明确的名称?为测试实现 toString 方法似乎没有帮助。

(这是 JUnit test with dynamic number of tests 的后续问题。)

最佳答案

我认为 jUnit 4 中内置没有任何东西可以做到这一点。

我已经实现了一个解决方案。我在现有的基础上构建了自己的 Parameterized 类:

public class MyParameterized extends TestClassRunner {
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Parameters {
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public static @interface Name {
}

public static Collection<Object[]> eachOne(Object... params) {
List<Object[]> results = new ArrayList<Object[]>();
for (Object param : params)
results.add(new Object[] { param });
return results;
}

// TODO: single-class this extension

private static class TestClassRunnerForParameters extends TestClassMethodsRunner {
private final Object[] fParameters;

private final Class<?> fTestClass;

private Object instance;

private final int fParameterSetNumber;

private final Constructor<?> fConstructor;

private TestClassRunnerForParameters(Class<?> klass, Object[] parameters, int i) throws Exception {
super(klass);
fTestClass = klass;
fParameters = parameters;
fParameterSetNumber = i;
fConstructor = getOnlyConstructor();
instance = fConstructor.newInstance(fParameters);
}

@Override
protected Object createTest() throws Exception {
return instance;
}

@Override
protected String getName() {
String name = null;
try {
Method m = getNameMethod();
if (m != null)
name = (String) m.invoke(instance);
} catch (Exception e) {
}
return String.format("[%s]", (name == null ? fParameterSetNumber : name));
}

@Override
protected String testName(final Method method) {
String name = null;
try {
Method m = getNameMethod();
if (m != null)
name = (String) m.invoke(instance);
} catch (Exception e) {
}
return String.format("%s[%s]", method.getName(), (name == null ? fParameterSetNumber : name));
}

private Constructor<?> getOnlyConstructor() {
Constructor<?>[] constructors = getTestClass().getConstructors();
assertEquals(1, constructors.length);
return constructors[0];
}

private Method getNameMethod() throws Exception {
for (Method each : fTestClass.getMethods()) {
if (Modifier.isPublic((each.getModifiers()))) {
Annotation[] annotations = each.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == Name.class) {
if (each.getReturnType().equals(String.class))
return each;
else
throw new Exception("Name annotated method doesn't return an object of type String.");
}
}
}
}
return null;
}
}

// TODO: I think this now eagerly reads parameters, which was never the
// point.

public static class RunAllParameterMethods extends CompositeRunner {
private final Class<?> fKlass;

public RunAllParameterMethods(Class<?> klass) throws Exception {
super(klass.getName());
fKlass = klass;
int i = 0;
for (final Object each : getParametersList()) {
if (each instanceof Object[])
super.add(new TestClassRunnerForParameters(klass, (Object[]) each, i++));
else
throw new Exception(String.format("%s.%s() must return a Collection of arrays.", fKlass.getName(), getParametersMethod().getName()));
}
}

private Collection<?> getParametersList() throws IllegalAccessException, InvocationTargetException, Exception {
return (Collection<?>) getParametersMethod().invoke(null);
}

private Method getParametersMethod() throws Exception {
for (Method each : fKlass.getMethods()) {
if (Modifier.isStatic(each.getModifiers())) {
Annotation[] annotations = each.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType() == Parameters.class)
return each;
}
}
}
throw new Exception("No public static parameters method on class " + getName());
}
}

public MyParameterized(final Class<?> klass) throws Exception {
super(klass, new RunAllParameterMethods(klass));
}

@Override
protected void validate(MethodValidator methodValidator) {
methodValidator.validateStaticMethods();
methodValidator.validateInstanceMethods();
}

}

像这样使用:

@RunWith(MyParameterized.class)
public class ParameterizedTest {
private File file;
public ParameterizedTest(File file) {
this.file = file;
}

@Test
public void test1() throws Exception {}

@Test
public void test2() throws Exception {}

@Name
public String getName() {
return "coolFile:" + file.getName();
}

@Parameters
public static Collection<Object[]> data() {
// load the files as you want
Object[] fileArg1 = new Object[] { new File("path1") };
Object[] fileArg2 = new Object[] { new File("path2") };

Collection<Object[]> data = new ArrayList<Object[]>();
data.add(fileArg1);
data.add(fileArg2);
return data;
}
}

这意味着我更早地实例化了测试类。我希望这不会导致任何错误......我想我应该测试测试:)

关于java - 在 Eclipse Testrunner 中具有名称的 ParameterizedTest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/385925/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com