Академический Документы
Профессиональный Документы
Культура Документы
/** * * Sumo uno a $_nombreParametro2 */ function sumarUno() { // No se le pasa parmetros puesto que se va a sumar // uno a $_nombreParametro2 que es propio de la clase. $this->_nombreParametro2 += 1; } /** * * Suma dos nmeros. * @param Float $numero1 * @param Float $numero2 * @return Float La suma de los dos nmeros. */ static function sumarDosNumeros($numero1, $numero2) { // Es esttica porque no se utiliza ningn campo // de la clase Ejemplo. // Sin embargo, se debe evitar la programacin de // funciones estticas puesto que no son adecuadas // para pruebas unitarias. return $numero1 + $numero2; } } ?>
MANEJO DE EXCEPCIONES
Para reportar errores en los procesos se utilizaran exepciones, procurando que las mismas representen el error que se produjo. Para esto se pueden definir exepciones personalizadas que sern lanzadas entre las capas. Las mismas se ubican en el archivo Entidades\CustomExceptions.php:
<?php /** * Clase que aade la funcionalidad de excepcin proveniente. * Se utiliza para almacenar la excepcin original. */ abstract class InnerException extends Exception { private $_innerException; /** * Inicializa una Exception del tipo InnerException * @param String $message * @param String $code * @param Exception $innerException */ public function __construct($message, $code, Exception $innerException) { parent::__construct ($message, $code); $this->_innerException = $innerException; } /** * @return InnerException La excepcin asociada. */ public function getInnerException() { return $this->_innerException; }
} return false;
/** * Excepcin que se produce por datos que el usuario * ingreso incorrectamente, o que el usuario los * puede corregir, ingresando nuevamente o por * parametrizacin. */ class UserException extends Exception {} ?>
CLASE DATABASE
Se utiliza para el acceso a la base de datos, implementando los procedimientos ms recurrentes. Se utiliza:
require_once '../DAL/Database.php';
Cuando en una Entidad llame a la BDD, slo tendra que manejar excepciones de tipo Db (personalizada) , y no preocuparse por capturar cada caso. En el caso de UserException, la capa de Lgica debera lanzarla y la interfaz grfica debera capturar esta excepcin para mostrarla al usuario. Se pueden aadir excepciones para controlar diferentes eventos, de ser necesario. Lgica del Negocio: >No recuperable:
try { $db->executeNonQuery($comm); } catch (FatalDbException $e) { //Validar si el error lo puede solucionar el usuario. Ej.: //Verificar si el error se produce por una clave fornea. if (stristr($e->getInnerException()->getMessage(), 'FK') === FALSE) { throw $e; //Relanzar la misma excepcin. } else { //Lanzar la excepcin personalizada a la capa de //interfaz grfica. throw new UserException('Uno o ms parmetros no estn en la BDD.'); } }
Es opcional poner las varibles del procedimiento almacenado con arroba @) > Agregar parmetros de entrada:
$db->addInParameter($comm,'PA_IDPAIS',$pais,SQLVARCHAR,false); $db->addInParameter($comm,'ID',$ID,SQLVARCHAR,false);
ACCESO A LA BDD
Se debe seguir la lgica de funciones bsicas CRUD: OPERACIN Create Read (Retrieve) Update SQL INSERT SELECT UPDATE TIPO NonQuery* Query** NonQuery* NonQuery*
*Que no devuelve una consulta. Puede devolver variables OUTPUT **Que devuleve una consulta. Las clases debern implementar las funciones CRUD, segn corresponda.
function insertar() { //Lgica adicional de insercin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[InsertarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm,'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); $db->addInParameter($comm, 'PARAM2', $this->_nombreParametro2, SQLFLT4, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; } }
NOTAS: - No se debe capturar exepciones que no se conoce el motivo. El objetivo de capturar una excepcin es procesarlas.
try { //Proceso que lanza una excepcin. //.. } catch (Exception $e) { //Se captura una excepcin genrica. echo $e->getMessage(); //No se sabe porque se produjo. //Para qu mostrar el error? }
function actualizar() { //Lgica adicional de actualizacin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[ActualizarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm, 'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); $db->addInParameter($comm, 'PARAM2', $this->_nombreParametro2, SQLFLT4, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; }
/** * Construye la prueba. Por defecto, sin valores. */ public function __construct() { } /** * Tests Ejemplo->getNombreParametro1() */ public function testGetNombreParametro1() { //Verifica si el valor de retorno es con el //que se inicializ. $this->assertEquals('Hola mundo', $this->Ejemplo->getNombreParametro1());
/** * Tests Ejemplo->getNombreParametro2() */ public function testGetNombreParametro2() { //Verifica si el valor de retorno es con el //que se inicializ. $this->assertEquals(1, $this->Ejemplo->getNombreParametro2()); } /** * Tests Ejemplo->setNombreParametro1() */ public function testSetNombreParametro1() { $this->Ejemplo->setNombreParametro1('Hola mundo 2'); //Verifica si en realidad cambio el valor //del atributo. $this->assertAttributeEquals('Hola mundo 2', '_nombreParametro1', $this->Ejemplo); } /** * Tests Ejemplo->setNombreParametro2() */ public function testSetNombreParametro2() { $this->Ejemplo->setNombreParametro2(0); //Verifica si en realidad cambio el valor //del atributo. $this->assertAttributeEquals(0, '_nombreParametro2', $this->Ejemplo); } /** * Tests Ejemplo->__toString() */ public function test__toString() { //Verifica que se devuelva el valor esperado. $this->assertEquals('Hola mundo', $this->Ejemplo->__toString()); } /** * Tests Ejemplo->__equals() */ public function test__equals() { $obj = new Ejemplo('Hola mundo'); $this->assertTrue($this->Ejemplo->__equals($obj)); } /** * Tests Ejemplo->sumarUno() */ public function testSumarUno() { $this->Ejemplo->sumarUno(); //Verifica si en realidad se sum uno al //valor del atributo. $this->assertAttributeEquals(2, '_nombreParametro2', $this->Ejemplo); } //Pruebas con proveedor de datos (verificando). /** * Tests Ejemplo::sumarDosNumeros() * Con proveedor de datos. * @dataProvider provider */ public function testSumarDosNumeros($numero1, $numero2, $resultado) { //La funcin provider() devuelve un array de arrays //que contiene los valores de entrada de este test. $this->assertEquals($resultado, Ejemplo::sumarDosNumeros($numero1, $numero2)); }
function eliminar() { //Lgica adicional de eliminacin. // ... //Insertar en la BDD. $db = new Database(); $commandString = '[dbo].[EliminarEjemplo]'; $comm = $db->getStoredProcCommand($commandString); $db->addInParameter($comm, 'PARAM1', $this->_nombreParametro1, SQLVARCHAR, false); try { $db->executeNonQuery($comm); } catch (Exception $e) { throw $e; }
PRUEBAS UNITARIAS
Se utiliza por estndar PHPUnit: Deben ser persitentes a lo largo del tiempo: no depender de datos actuales. Deben ser automticas: no deben tener variables de ingreso. Deben verificar todos los casos de uso de una funcin, pero uno por uno. Se deben programar antes de programar la funcin o la clase. (TDD: Test-Driven Development; Desarrollo Guiado por Pruebas). En general, la lgica del negocio se debe programar en las Clases, pero si un mtodo utiliza un Procedimiento Almacenado (PA), el programador del PA ser quien haga la prueba unitaria en la BDD; y el programador de la aplicacin validar nicamente que este devuelva el valor correcto de retorno, o en su defecto que no devuelva un error en el caso feliz.
<?php require_once 'Entidades\Ejemplo.php'; require_once 'PHPUnit\Framework\TestCase.php'; class EjemploTest extends PHPUnit_Framework_TestCase { /** * @var Ejemplo */ private $Ejemplo; /** * Prepara el entorno antes de ejecutar la prueba. */ protected function setUp() { parent::setUp (); // Inicializa la clase ejemplo. $this->Ejemplo = new Ejemplo('Hola mundo',1); } /** * Limpia el entorno despus de ejecutar la prueba. */ protected function tearDown() { // Establece en null el objeto para liberar memoria. $this->Ejemplo = null; } parent::tearDown ();
public function provider() { return array( array(1, 2, 3), array(-1, -2, -3), array(1, -2, -1), array(-2, 1, -1) ); } //Pruebas con dependencia. /** * Tests sumar uno con dependencia */ public function testSumarUnoDependencia() { $this->Ejemplo->sumarUno(); $this->assertAttributeEquals(2, '_nombreParametro2', $this->Ejemplo); //Una vez que se ha superado la prueba, //se devuelve el objeto modificado que //sirve de ingreso para la siguiente prueba: return $this->Ejemplo; }
/** * Tests recuperar valor con dependencia. * @depends testSumarUnoDependencia */ public function testGetNombreParametro2Dependencia( Ejemplo $obj) { //En setUp() se inicializ en 1, en el test //dependiente se sum uno al valor (actual 2). //En esta funcin, se pasa de parmetro el //resultado del test anterior. Por lo tanto, //la aseveracin es correcta pues el valor //comparado es 2. $this->assertEquals(2, $obj->getNombreParametro2()); }
NOTAS: Los test son independientes, no importa el orden en que se ejecuten las funciones. Slo son dependientes cuando se indica explcitamente con la anotacin @depends.