2011-09-26 20 views
15
@DataPoints public static final Integer[] input1={1,2}; 
@Theory 
@Test 
public void test1(int input1){ 

} 

@DataPoints public static final Integer[] input2={3,4}; 
@Theory 
@Test 
public void test2(int input2){ 

} 

Quiero que test1 se ejecute con el conjunto de datos input1 - {1,2} y test2 se ejecuta con input2 - {3,4}. Pero actualmente cada prueba se ejecuta con los dos conjuntos de datos {1,2,3,4}. Cómo enlazar un @DataPoints específico con @Theorys específicos¿Cómo adjuntar un DataPoint con una Teoría?

Respuesta

22

Los DataPoints se aplican a la clase. Si tiene un método @Theory que toma un int, y usted tiene un DataPoint que es una matriz de ints, entonces se llamará con el int.

@RunWith(Theories.class) 
public class TheoryTest { 
    @DataPoint public static int input1 = 45; 
    @DataPoint public static int input2 = 46; 
    @DataPoints public static String[] inputs = new String[] { "foobar", "barbar" }; 

    @Theory public void testString1(String input) { 
     System.out.println("testString1 input=" + input); 
    } 

    @Theory public void testString2(String input) { 
     System.out.println("testString2 input=" + input); 
    } 

    @Theory public void test1(int input) { 
     System.out.println("test1 input=" + input); 
    } 

    @Theory public void test2(int input) { 
     System.out.println("test2 input=" + input); 
    } 
} 

Para esto se necesitan test1 con 45 & 46 y test2 con 45 & 46. Se llama testString1 con "foobar" y "barbar" y testString2 con "foobar" y "barbar".

Si realmente desea utilizar diferentes conjuntos de datos para diferentes teorías, se puede envolver los datos en una clase privada:

@RunWith(Theories.class) 
public class TheoryTest { 
    public static class I1 { int i; public I1(int i) { this.i = i;} } 
    public static class I2 { int i; public I2(int i) { this.i = i;} } 

    @DataPoint public static I1 input1 = new I1(45); 
    @DataPoint public static I2 input2 = new I2(46); 

    @Theory 
    public void test1(I1 input) { 
     System.out.println("test1 input=" + input.i); 
    } 

    @Theory 
    public void test2(I2 input) { 
     System.out.println("test2 input=" + input.i); 
    } 
} 

Esto exige test1 test2 con 45 y con 46. Esto funciona, pero en mi opinión, oscurece el código, y puede ser una mejor solución simplemente dividir la clase de prueba en dos clases.

+0

@Mathew Gracias por la respuesta. Entonces no hay ninguna característica vinculante como tal. Usará el envoltorio en clase privada por el momento. Pero aún no es elegante. Todavía no entiendo por qué los DataPoints están adjuntos a la clase? Tienen más sentido a nivel de método. –

+0

La idea es que tenga una cantidad de puntos de datos, y puede probar una cantidad de teorías: para eso necesita una cantidad de métodos de prueba. Si está satisfecho con la respuesta, ¿puede aceptarla, por favor? –

+0

+1 para dividir la clase de prueba en dos clases. Si test1 y test2 necesitan diferentes conjuntos de datos para pasar y tener sentido, entonces esencialmente están probando diferentes comportamientos y lógicamente pueden separarse. –

1

Algunas de las referencias que he visto hablar sobre el uso de pruebas de valores específicos y teorías para verificar el comportamiento. Como ejemplo, si tiene una clase que tiene métodos para sumar y restar de un atributo, una prueba verificaría la corrección del resultado (por ejemplo, 1 + 3 devuelve 4) mientras que una teoría podría verificar eso, para los valores del punto de datos (x1) , y1), (x2, y2), x + yy siempre es igual a x, x-y + y siempre es igual a x, x * y/y siempre es igual a x, etc. De esta forma, los resultados de las teorías no se acoplan tan estrechamente con los datos. Con las teorías, también puede filtrar casos como y == 0; ellos no cuentan como fracaso. En pocas palabras: puedes usar ambos. Un buen trabajo es: http://web.archive.org/web/20110608210825/http://shareandenjoy.saff.net/tdd-specifications.pdf

21

Con JUnit 4.12 (no estoy seguro cuando se introdujo) es posible nombrar los puntos de datos y asignarlos a parámetros (lo aprendí de http://farenda.com/junit/junit-theories-with-datapoints/):

@RunWith(Theories.class) 
public class TheoriesAndDataPointsTest { 
    @DataPoints("a values") 
    public static int[] aValues() { 
     return new int[]{1, 2}; 
    } 

    @DataPoints("b values") 
    public static int[] bValues() { 
     return new int[]{3, 4}; 
    } 

    @Theory 
    public void theoryForA(@FromDataPoints("a values") int a) { 
     System.out.printf("TheoryForA called with a = %d\n", a); 
    } 

    @Theory 
    public void theoryForB(@FromDataPoints("b values") int a) { 
     System.out.printf("TheoryForB called with b = %d\n", a); 
    } 
} 

Salida:

TheoryForA called with a = 1 
TheoryForA called with a = 2 
TheoryForB called with b = 3 
TheoryForB called with b = 4 
+1

Esta debería ser la respuesta aceptada. – Chris311

+0

@ Chris311, debería, pero solo para aquellos que pueden usar la última JUnit. Desafortunadamente para nosotros, atascados con versiones anteriores de IDE, el eclipse hasta al menos un cierto punto (y estoy seguro de que todavía lo es) insiste en usar su propia versión preempaquetada de la biblioteca JUnit, que podría no ser compatible con esto. –

Cuestiones relacionadas