2010-11-22 13 views
0

So versuche ich den JUnit Parameterized Test Runner auf eine Last von einzelnen generischen typisierten Objekten aufzurufen. Die zu verwendenden spezifischen Klassen sind den untergeordneten Klassen bekannt.Wie kann ich einen JUnit parametrisierten Test-Runner für eine Sammlung generischer Typen aufrufen?

Ursprünglich gelang es mir, eine Methode zu erhalten, die Collection<T> für JUnit zu arbeiten, aber dann erkannte ich JUnit tatsächlich eine Collection<T[]> - Ich habe Probleme beim Erstellen dieses Array wegen Javas Zurückhaltung/Verweigerung, Arrays von Generika zu erstellen .

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; 
} 

Jetzt JUnit erfordert eine Collection<T[]> wie folgt aus:

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

Also, indem Sie etwas, um die Rückgabetyp wie ich will ändern:

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; 
} 

Leider Java lassen mich nicht tun Dies liegt daran, dass Sie keine generischen Arrays erstellen können.

Ich bin versucht, die Aussage als result.add((T[])new Object[]{someBean}); setzen, aber ist das sicher? oder gibt es einen besseren Weg?

+0

„JUnit tatsächlich erfordert eine Sammlung "Warum benötigt es das? Es scheint irgendwie komisch – user102008

Antwort

-1

Sie können versuchen, eine List<T> verwenden und dann die toArray(T[]) Methode verwenden, und Sie erhalten eine T[]. mit Collections.singletonList(T o)

+2

Leider helfen diese nicht: 'toArray()' gibt ein 'Object []' anstatt 'T []' zurück, was identisch ist mit 'new Object [] {someBean}' wie in meinem Beispiel, und 'singletonList' gibt eine' List' anstatt eines Arrays wie von JUnit erwartet zurück. Die Ein-Argument-Form 'toArray (T [])' gibt ein 'T []' zurück, aber Sie müssen immer noch das generische Array erstellen, um es an die 'toArray'-Methode zu übergeben, also ist es keine Hilfe ... – Kidburla

+0

toArray() gibt zurück Object [], toArray (T []) liefert T [] – greuze

0

Es ist peinlich, wie die Hölle

können Sie auch eine generische Liste mit nur einem Element erstellen, sollte aber folgende Arbeiten:

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

Cf .:

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); 
     } 
    } 
} 

Wenn Du bist wirklich wirklich sicher, dass es sicher ist, könnten Sie someClass überspringen und einfachverwenden 10, aber dann laufen Sie das Risiko, dass someObject ist eine Unterklasse von T anstatt T selbst, die in dem obigen Fall würde Sie eine ArrayStoreException versuchen, 2.5 in eine Integer[] setzen.

(Beachten Sie aber, dass, wenn Sie Vergangenheit, die erhalten - wenn Sie Integers speichern -.. Java werden Sie entkommen lassen mit Gießen dass Integer[] zu einem Number[] Frag mich nicht warum)