2010-11-22 50 views
0

所以我试图调用JUnit Parameterized测试运行器对单个泛型类型对象的加载。要使用的具体类是后代类已知的。如何在一组泛型类型上调用JUnit Parametrized测试运行器?

本来我设法得到一个返回Collection<T>供JUnit使用的方法,但后来我意识到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});,但这是安全的吗?或者,还有更好的方法?

+0

“实际的JUnit需要收集“为什么需要这个?看起来有些奇怪 – user102008 2013-02-06 08:37:31

回答

-1

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

你也可以创建一个通用的清单只使用一个元素Collections.singletonList(T o)

+2

不幸的是,这些并没有帮助:'toArray()'返回一个'Object []'而不是'T []'与'new Object [] {someBean}'相同, 'singletonList'返回一个List,而不是JUnit所期望的数组。单参数形式'toArray(T [])'返回一个'T []',但你仍然必须创建通用数组传递给'toArray'方法,所以它没有帮助... – Kidburla 2010-11-22 12:21:38

+0

toArray()返回Object [],toArray(T [])返回T [] – greuze 2013-02-06 08:42:16

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(),但那么你冒着someObjectT的子类而不是T本身的风险,在上述情况下,它会让你尝试将2.5置于Integer[]中的ArrayStoreException

(但请注意,如果你过去是 - 如果你只存储Integers - 。java会让你流延Integer[]Number[]脱身不要问我为什么)