如何在泛型类型集合上调用JUnit参数化测试运行器?

时间:2010-11-22 10:39:00

标签: java generics junit parameterized-unit-test

所以我试图在一堆个别泛型类型对象上调用JUnit Parameterized测试运行器。要使用的特定类是后代类已知的。

最初我设法得到一个方法,为JUnit返回一个Collection<T>,然后我意识到JUnit实际上需要一个Collection<T[]> - 由于Java的不情愿,我在创建这个数组时遇到了麻烦/拒绝创建泛型数组。

protected static <T> Collection<T> someMethod(Class<T> someClass)
{
    Collection<T> result = new ArrayList<T>();
    T someBean;
    while (someCondition(...))
    {
        //Do some stuff to compute someBean

        result.add(someBean);
    }
    return result;
}

现在JUnit需要这样的Collection<T[]>

// (descendant class)
@Parameters
public static Collection<SomeActualClass[]> data()
{
    return someMethod(SomeActualClass.class);
}

所以我想通过执行以下操作来更改返回类型:

protected static <T> Collection<T[]> someMethod(Class<T> someClass)
{
    Collection<T[]> result = new ArrayList<T>();
    T someBean;
    while (someCondition(...))
    {
        //Do some stuff to compute someBean

        result.add(new T[]{someBean});
    }
    return result;
}

不幸的是,Java不允许我这样做,因为你无法创建通用数组。

我很想把陈述作为result.add((T[])new Object[]{someBean});但是这样安全吗?还是有更好的方法?

2 个答案:

答案 0 :(得分:0)

地狱很尴尬,但以下情况应该有效:

T[] theArray = (T[]) Array.newInstance(someClass, 1);
theArray[0] = someBean;

比照:

public class Foo<T> {

    final T t0;
    final T t1;
    final Class theClass;

    public Foo(T t0, T t1, Class<T> theClass) {
        this.t0 = t0;
        this.t1 = t1;
        this.theClass = theClass;
    }

    @SuppressWarnings("unchecked")
    public T[] getStuffArray() {
        T[] theArray = (T[]) Array.newInstance(theClass, 2);
        System.out.println(theArray.getClass().getName());
        theArray[0] = t0;
        theArray[1] = t1;
        return theArray;
    }

    public static void main(String[] args) {

        Number[] stuffArray = new Foo<Number>(1, 2.5, Number.class).getStuffArray();
        for (Number s: stuffArray) {
            System.out.println(s);
        }
    }
}

如果你非常确定它是安全的,你可以跳过someClass并使用someObject.getClass(),但是你会冒someObject的风险是T而不是T本身的子类,在上述情况下会让ArrayStoreException尝试将2.5放入Integer[]

(请注意,如果你过去了 - 如果你只存储Integers - java会让你将Integer[]转换为Number[]。问我为什么。)

答案 1 :(得分:-1)

您可以尝试使用List<T>,然后使用toArray(T[])方法,您将获得T[]

您还可以使用Collections.singletonList(T o)

创建一个只包含一个元素的通用列表