我将测试用例添加到测试套件中,如下所示:
for(String methodName : getPublicDeclaredMethods(TestA.class))
{
this.addTest((new TestA(methodName)));
}
for(String methodName : getPublicDeclaredMethods(TestB.class))
{
this.addTest((new TestB(methodName)));
}
这相当于这样做:
this.addTest((new TestA("TEST_METHOD_1")));
this.addTest((new TestA("TEST_METHOD_2")));
this.addTest((new TestB("TEST_METHOD_1")));
this.addTest((new TestB("TEST_METHOD_3"))); // woops I forgot TEST_METHOD_2
我坚持使用这个奇怪的测试框架,其中方法名称通过构造作为字符串提供。
我上面的代码保证我添加在特定类中定义的所有测试用例。但是,我希望有一个看起来像这样的方法:
void <T> addTestCasesFromClass()
{
for(String methodName : getPublicDeclaredMethods(T.class))
{
this.addTest((new T(methodName)));
}
}
但我不确定这是如何在Java中完成的。它甚至可能吗? TestA和TestB派生自Test。
答案 0 :(得分:1)
泛型在这里没用,因为你不能做new T
之类的事情。但你可以用更多的反思来做到这一点。鉴于您传递给此方法的所有类都具有一个构造函数,该构造函数只接受一个String参数。
void addTestCasesFromClass(Class<?> clz)
{
for(String methodName : getPublicDeclaredMethods(clz))
{
this.addTest(clz.getConstructor(String.class).newInstance(methodName));
}
}
电话会看起来像这样
addTestCasesFromClass(TestA.class);
addTestCasesFromClass(TestB.class);
如果您的addTest
方法只接受某个基类的对象(让它为TestBase
),则将clz
的通用参数更改为Class<? extends TestBase> clz
。
答案 1 :(得分:1)
当您只引用Generic类型时,无法实例化。 泛型仅在编译时可用,因此您无法在运行时使用它们。 这意味着您将需要对实际类Class的引用,并通过反射实例化它。
Class<?> clazz = ...
Object instance = clazz.newInstance();
虽然鼓励使用getConstructor。
这方面的一个很好的例子是java中的List.toArray方法,它要求你传递一个数组实例,这样它才能实际引用Class,因为泛型在运行时不可用。
答案 2 :(得分:1)
您可以使用反射来查找您传递的接受字符串参数的类的构造函数。然后使用您检索的方法名称实例化您的类。
public <T> void addTestClassesFromClass(T item){
try {
Constructor<?> constructor = item.getClass().getConstructor(String.class);
for(String methodName : getPublicDeclaredMethods(item.getClass())){
this.addTest((constructor.newInstance(methodName)));
}
} catch (Exception e) {
System.out.println("Oh crap!");
}
}
答案 3 :(得分:0)
这是我的尝试:
public void addTestCasesFromClass(Class<? extends Test> c) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
for(String methodName : getPublicDeclaredMethods(c))
{
this.addTest((c.getDeclaredConstructor(String.class).newInstance(methodName)));
}
}