Академический Документы
Профессиональный Документы
Культура Документы
Como se observa, representamos el hecho de que en nuestro banco hay Cuentas y Tarjetas de
Crédito y de Débito, que están asociadas a una cuenta. Las operaciones que se realizan sobre una
Cuenta quedan registradas en un Vector de objetos de clase Movimiento, ocurriendo lo mismo con las
tarjetas de Crédito. En Tarjeta, todas las operaciones son abstractas excepto el constructor y
setCuenta(Cuenta), si bien no se señalan como tales porque no lo permite la herramienta utilizada
(Oracle JDeveloper 9.0.5).
Clase Cuenta.
package dominio;
import java.util.Vector;
Clase Movimiento.
package dominio;
import java.util.Date;
public Movimiento()
{
mFecha=new Date();
}
import java.util.Date;
import java.util.Date;
import java.util.Vector;
import java.util.Date;
Pruebas de Cuenta
package dominio.test; Ubicamos la clase en un paquete
diferente con objeto de mantener
import junit.framework.Test; adecuadamente organizado el código.
import junit.framework.TestCase; Importamos lo que necesitamos de
import junit.framework.TestSuite;
JUnit.
import dominio.Cuenta;
assertTrue(cuenta.getSaldo()==700.0);
}
En el méodo main llamamos al
public static void main(String args[])
{ TestRunner, diciéndole que ejecute
junit.swingui.TestRunner.run(CuentaTester1.class); esta clase de prueba.
}
}
import dominio.Cuenta;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import dominio.Debito;
import java.util.Date;
public void testRetirar1000() Probamos a ver qué pasa al retirar 1000 euros con la tarjeta.
{ Según el código de la clase Debito, el importe se retira de
try manera inmediata de la cuenta asociada (en la que hay 1000
{ euros porque así lo hemos dicho en el método setUp).
debito.retirar(1000.0);
Pruebas de Credito
package dominio.test;
import java.util.Date;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import dominio.Credito;
import dominio.Cuenta;
public void testIngresar500() Probamos a ver qué pasa si ingresamos 500 euros con esta
{ tarjeta de crédito. Según el código, deben ingresarse en la
try cuenta asociada a la tarjeta.
{
double saldoAnteriorCuenta=cuenta.getSaldo(); Guardo en unas variables el crédito y el saldo de la tarjeta,
double saldoAnteriorTarjeta=tarjeta.getSaldo(); así como el saldo de la cuenta justo antes de ejecutar la
double creditoAnterior=tarjeta.getCreditoDisponible(); operación.
tarjeta.ingresar(500.0); Ingreso los 500 euros.
assertTrue(cuenta.getSaldo()==saldoAnteriorCuenta+500); Compruebo que el saldo de la cuenta es el saldo anterior
más el importe ingresado.
assertTrue(tarjeta.getSaldo()==saldoAnteriorTarjeta); Compruebo que el saldo de la tarjeta no ha variado.
assertTrue(tarjeta.getCreditoDisponible()==creditoAnterior); Compruebo que tampoco ha variado el código de la tarjeta.
}
catch (Exception e)
{
}
}
public void testRetirar300() Compruebo qué pasa al retirar 3000 euros. Según el código
{ fuente de Credito, la retirada de efectivo con este tipo de
try tarjeta lleva una comisión del 5% del importe, con un mínimo
{ de 3 euros.
double saldoAnteriorCuenta=cuenta.getSaldo();
double saldoAnteriorTarjeta=tarjeta.getSaldo(); Guardo los datos anteriores a la retirada.
double creditoAnterior=tarjeta.getCreditoDisponible();
tarjeta.retirar(300.0); Retiro los 300 €
assertTrue(cuenta.getSaldo()==saldoAnteriorCuenta); Compruebo que la operación no ha afectado a la Cuenta
(porque es una operación a crédito)
public void testLiquidar() Cuando una tarjeta de crédito se liquida, se toman todos su
{ movimientos del mes, se suman los importes y se hace el
try cargo a la cuenta asociada correspondiente. En este método
{ pruebo esta funcionalidad.
double saldoAnteriorCuenta=cuenta.getSaldo();
tarjeta.pagoEnEstablecimiento("Zara", 120.0);
tarjeta.pagoEnEstablecimiento("El Corte Inglés", 230.0); Este mes he pagado 350 euros en dos compras.
tarjeta.liquidar(11, 2003); Hago la liquidación.
assertTrue(saldoAnteriorCuenta==cuenta.getSaldo()- Compruebo que el saldo actual de la cuenta es 350 euros
350.0); inferior al que había antes de liquidar.
}
catch (Exception e)
{
}
}
Es decir, funciona el último método (el encargado de hacer la liquidación), pero fallan los otros dos.
Podemos reescribir el método testIngresar500 para facilitar el proceso de depuración:
public abstract class TarjetaTester1 extends TestCase Declaramos esta clase como abstracta
{
Tarjeta tarjeta; Declaramos dos fixtures.
Cuenta cuenta;
public abstract Tarjeta preparaTarjeta(Cuenta c); Declaramos un método abstracto que me devuelve un objeto de clase
Tarjeta, objeto que será adecuado para todas las especializaciones de
esta clase de prueba.
public abstract Tarjeta tarjetaInicial(); Este método me devolverá la fixture tarjeta.
public void testRetirar300() Tanto con las tarjetas de débito como con las de crédito puedo retirar
{ dinero. Por tanto, puede describirse esta funcionalidad mezclando
try operaciones concretas y abstractas, mediante lo que sería un patrón
{ Método-plantilla.
Tarjeta tarjeta=tarjetaInicial(); Obtengo la tarjeta inicial, que a veces será de débito y a ves de crédito.
tarjeta.retirar(300.0); Retiro 300 euros.
public class DebitoTester2 extends TarjetaTester1 Ya no especializo a TestCase, sino a la clase abstracta anterior
{
public DebitoTester2(String sTestName)
{
super(sTestName);
}
public void setUp() throws Exception En este setUp llamo en primer lugar al setUp del padre para que
{ construya la fixture cuenta, declarada arriba...
super.setUp();
Date hoy=new Date();
long tiempo=Long.parseLong("12096000000");
Date fecha=new Date(hoy.getTime()+ tiempo); // Caduca
en 4 años ...y luego construyo la fixture tarjeta, declarada arriba pero que
tarjeta=new Debito("1234567890123456", "Fulano de Tal",
debe ser instanciada en las subclases.
fecha);
tarjeta.setCuenta(cuenta);
}
public Tarjeta preparaTarjeta(Cuenta c) Me construyo una tarjeta ad hoc, de débito en este caso, a la
{ que asocio la fixture cuenta declarada y creada en la superclase.
Tarjeta t=new Debito("9876543210987654", "Paco Pil",
null);
t.setCuenta(cuenta);
return t;
}
public Tarjeta preparaTarjeta(Cuenta c) Creo una tarjeta ad hoc, en este caso de crédito
{
Tarjeta t=new Credito("9876543210987654", "Paco Pil",
null, 1000.0);
t.setCuenta(c);
Movimiento m=new Movimiento();
m.setImporte(-315.0);
((Credito) t).addMovimiento(m);
return t;
}
En este ejemplo, debemos ejecutar de forma separada las dos especializaciones de la clase de prueba abstracta.
Clase Cuenta.
package dominio;
import java.util.Vector;
import java.sql.*;
import com.mockobjects.sql.MockPreparedStatement;
import com.mockobjects.sql.MockMultiRowResultSet; Importamos las clases Mock que necesitemos
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import dominio.Cuenta;
import com.mockobjects.sql.MockConnection2;
Importamos la MockConnection2 en lugar de la
MockConnection normal, que parece ser que
no funciona correctamente.
public class CuentaConMock extends TestCase La clase es una especialización de TestCase
{
Cuenta cuenta; Ponemos dos fixtures: una cuenta y una “falsa”
MockConnection2 bd; conexión a base de datos.
Todas las clases MockX son especializaciones de X: por ejemplo, MockPreparedStatement es una
java.sql.PreparedStatement. En la siguiente figura vemos la estructura de las tres clases mock utilizadas en el ejempllo
anterior: