2010-11-22 12 views
0

J'essaye donc d'appeler le coureur de test JUnit Parameterized sur un chargement d'objets typés génériques individuels. Les classes spécifiques à utiliser sont connues des classes descendantes.Comment appeler un coureur de test JUnit Parametrized sur une collection de types génériques?

Au départ, je réussi à obtenir une méthode qui retourne un Collection<T> pour JUnit travailler avec, mais je réalise JUnit exige en fait un Collection<T[]> - Je vais avoir du mal à créer ce tableau en raison de la réticence de Java/refus de créer des tableaux de génériques .

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

Maintenant JUnit nécessite une Collection<T[]> comme ceci:

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

Je veux changer le type de retour en faisant quelque chose comme:

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

Malheureusement Java ne me laisse pas faire ceci parce que vous ne pouvez pas créer de tableaux génériques.

Je suis tenté de mettre l'instruction comme result.add((T[])new Object[]{someBean}); mais est-ce sûr? ou y a-t-il un meilleur moyen?

+0

« JUnit fait nécessite une Collection "Pourquoi cela exige-t-il cela? Cela semble un peu étrange – user102008

Répondre

-1

Vous pouvez essayer d'utiliser un List<T> et ensuite utiliser la méthode toArray(T[]), et vous obtiendrez un T[].

Vous pouvez également créer une liste générique avec un seul élément en utilisant Collections.singletonList(T o)

+2

Malheureusement, cela n'aide pas: 'toArray()' renvoie un 'Object []' plutôt que 'T []' qui est identique à 'new Object [] {someBean}' comme dans mon exemple, et 'singletonList' renvoie un' List' plutôt qu'un tableau comme attendu par JUnit. La forme à un argument 'toArray (T [])' renvoie un 'T []' mais vous devez toujours créer le tableau générique pour passer dans la méthode 'toArray', donc ce n'est pas utile ... – Kidburla

+0

toArray() retourne Object [], toArray (T []) renvoie T [] – greuze

0

Il est maladroit comme l'enfer, mais ce qui suit devrait fonctionner:

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

Si vous êtes vraiment vraiment sûr que c'est sûr, vous pouvez passer someClass et juste utiliser someObject.getClass(), mais vous courez le risque que someObject est une sous-classe de T plutôt que T lui-même, qui, dans le cas ci-dessus obtiendriez-vous un ArrayStoreException essayer de mettre 2.5 dans un Integer[].

(Notez bien que si vous avez passé - si vous stockez seulement Integers -.. Java vous permettra de sortir avec la coulée qui Integer[] à un Number[] Ne me demandez pas pourquoi)