Vamos a ver la diferencia entre @Before vs @BeforeClass dos de las anotaciones más utilizadas en JUnit a la hora de organizar nuestro código y sus inicializaciones. Para ello vamos a partir de dos pruebas unitarias sencillas usando la clase Factura que contiene una lista de lineas que son valores de tipos doble.
package com.arquitecturajava.test; import java.util.ArrayList; import java.util.List; public class Factura { private List<Double> lineas= new ArrayList<Double>(); public List<Double> getLineas() { return lineas; } public void setLineas(List<Double> lineas) { this.lineas = lineas; } public void addLinea(double linea) { lineas.add(linea); } public double sumarLineas () { double total=0; for (double linea: lineas) { total+=linea; } return total; } public double mayor () { double mayor=0; for (double linea: lineas) { if (mayor<linea) { mayor=linea; } } return mayor; } }
JUnit y pruebas unitarias
Una vez construida la clase podemos definir un par de pruebas unitarias sencillas que comprueben los métodos sumarLineas() y mayor(). Algo similar a lo siguiente podría valer:
package com.arquitecturajava.test; import static org.junit.Assert.assertEquals; import org.junit.Test; public class FacturaTest { @Test public void sumaTest() { Factura f= new Factura(); f.addLinea(100); f.addLinea(200); assertEquals(300,f.sumarLineas(),0); } @Test public void mayorTest() { Factura f= new Factura(); f.addLinea(100); f.addLinea(200); assertEquals(200,f.mayor(),0); } }
Acabamos de pasar dos pruebas unitarias con JUnit :
¿Son estas pruebas unitarias correctas? . La realidad es que no tienen problemas pero sí que es cierto que comparten mucho código. Es decir tenemos mucho código repetido. Podemos apoyarnos en @Before como anotación de JUnit para crear un método de inicialización que se encargue de iniciar la Factura con sus lineas .
package com.arquitecturajava.test; import static org.junit.Assert.assertEquals; import org.junit.After; import org.junit.Before; import org.junit.Test; public class FacturaTest2 { Factura f; @Before public void inicializar() { f = new Factura(); f.addLinea(100); f.addLinea(200); } @Test public void sumaTest() { assertEquals(300, f.sumarLineas(), 0); } @Test public void restaTest() { assertEquals(200, f.mayor(), 0); } @After public void finaliza() { f=null; } } En este caso hemos usado no solo @Before sino también @After . Estas anotaciones ejecutarán su funcionalidad cada vez que comience y termine cada uno de los Test . De esta forma nos encontramos con un código mas simplificado y reutilizable.
Junit @Before vs @BeforeClass
Sin embargo existen situaciones en las cuales a nosotros nos puede interesar iniciar una clase o una variable una sola vez para todos los test ya que todos la comparten y solo necesitan instanciarla la primera vez. Imaginemonos que tenemos un método adicional que calcula la suma de facturas con el IVA.
public double sumarLineasConIVA(double porcentaje) { return sumarLineas()+sumarLineas()/100*porcentaje; }
Se trata de un método muy sencillo pero igual el IVA a aplicar a las facturas se tiene que calcular primero con un servicio aparte.
package com.arquitecturajava.test; public class ServicioFacturas { public static double obtenerIVA() { return 21; } }
Podemos usar la anotación @BeforeClass para invocar a este servicio y poner a nuestra disposición el porcentaje de IVA.
public class FacturaTest3 { Factura f; double IVA; @BeforeClass public static void inicializadorComun() { IVA=ServicioFacturas.obtenerIVA(); } .....
Una vez construido este método podemos crear un nuevo test que nos valide el método sumarLineasConIVA.
@Test public void sumaConIVATest() { assertEquals(363, f.sumarLineasConIVA(IVA), 0); }
Todos los test se ejecutan correctamente y el IVA es calculado:
Acabamos de ver la diferencia entre @Before vs @BeforeClass en JUnit .
Cada día es más importante construir pruebas unitarias para nuestro código ya que aportará seguridad y flexibilidad a lo que construimos.
Osea before class solo se inicializa cuando se llama desde otra clase a un atributo o metodo de la prueba bofore class?
Se usa cuando hay q inicializar una vez algo para todo ese grupo de test , pero solo una vez