2010-08-16 20 views
6

Escribí un ejemplo de maqueta para ilustrar esto sin exponer nada confidencial. Es un ejemplo "ficticio" que no hace nada, pero el problema ocurre en el inicializador de prueba.¿Cómo utilizo un corredor JUnit Parametrizado con un constructor varargs?

@RunWith(Parameterized.class) 
public class ExampleParamTest 
{ 
int ordinal; 
List<String> strings; 

public ExampleParamTest(int ordinal, String... strings) 
{ 
    this.ordinal = ordinal; 
    if (strings.length == 0) 
    { 
    this.strings = null; 
    } 
    else 
    { 
    this.strings = Arrays.asList(strings); 
    } 
} 

@Parameters 
public static Collection<Object[]> data() { 
    return Arrays.asList(new Object[][] { 
    {0, "hello", "goodbye"}, 
    {1, "farewell"} 
    }); 
} 

@Test 
public void doTest() { 
    Assert.assertTrue(true); 
} 
} 

Básicamente tienen un constructor de prueba que acepta varios argumentos para una variable lista local y quiero llenar esto a través de un inicializador de matriz. El método de prueba manejará correctamente la variable de la lista local. He eliminado esta lógica para simplificar la prueba.

Cuando escribo esto, mi IDE no tiene quejas sobre la sintaxis y las compilaciones de la clase de prueba sin ningún error de compilación. Sin embargo, cuando lo ejecuto, me sale:

doTest[0]: 
java.lang.IllegalArgumentException: wrong number of arguments 
    at java.lang.reflect.Constructor.newInstance(Unknown Source) 
doTest[1]: 
java.lang.IllegalArgumentException: argument type mismatch 
    at java.lang.reflect.Constructor.newInstance(Unknown Source) 

¿Qué es exactamente que ha ido mal aquí, y cómo puedo usar correctamente este patrón?

+0

¿Qué es doTest y qué datos contiene? – Jes

+0

En este ejemplo, doTest es solo una prueba ficticia para permitir que esta suite de pruebas se ejecute en JUnit. El problema no está en el código de prueba, como verá cuando intente ejecutar esta prueba tal como está; a pesar de que tiene un cuerpo de prueba casi vacío, sigue sin funcionar debido al error de inicialización antes mencionado. – Kidburla

+0

Agregué parte de la stacktrace que veo cuando ejecuto la prueba para dejar en claro que el error ocurre cuando se invoca el constructor varargs. Si eso es diferente de lo que está viendo, siéntase libre de cambiarlo o revertirlo. –

Respuesta

11

No puedo probarlo ahora pero supongo que si invoca un método o un constructor con argumentos variables, debe invocarlo con una matriz en lugar de una lista de valores variables.

Si estoy en lo cierto, entonces esto debería funcionar:

@Parameters 
public static Collection<Object[]> data() { 
    return Arrays.asList(new Object[][] { 
    {0, new String[]{"hello", "goodbye"}}, 
    {1, new String[]{"farewell"}} 
    }); 
} 

algunas explicaciones

El nivel de código fuente, podemos escribir

test = ExampleParamTest(0, "one", "two"); 

El compilador convertir este a una matriz de cadenas. JUnit utiliza el API de reflexión y de invocación, y desde esta perspectiva, la firma de constructores es

public ExampleParamTest(int i, String[] strings); 

Así que para invocar el constructor - y eso es lo JUnit está haciendo internamente - usted tiene que pasar un entero y una matriz de cadenas.

+0

Lo probé, funciona. –

+0

Tienes razón, esto funcionó. Pero no es universalmente cierto. Normalmente, podría escribir algo como: myTest = new ExampleParamTest (0, "hola", "adiós"); Este es el punto completo de los métodos de argumento variable. ¿Por qué entonces esto no funciona en mi ejemplo? – Kidburla

Cuestiones relacionadas