2

我将测试用例添加到测试套件中,如下所示:

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 类。

4

4 回答 4

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),那么将泛型参数更改clzClass<? extends TestBase> clz

于 2013-02-27T13:02:15.387 回答
1

当您只有对 Generic 类型的引用时,您无法实例化。泛型仅在编译时可用,因此您不能在运行时使用它们。这意味着您将需要对实际类 Class 的引用并通过反射将其实例化。

Class<?> clazz = ...
Object instance = clazz.newInstance();

不过,鼓励使用 getConstructor 。

一个很好的例子是 java 中的 List.toArray 方法,它要求您传递数组的一个实例,以便它能够实际引用该类,因为泛型在运行时不可用。

于 2013-02-27T13:02:36.383 回答
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!");
    }
}
于 2013-02-27T13:03:16.057 回答
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)));
    }
}
于 2013-02-27T13:06:20.047 回答