Documentos de Académico
Documentos de Profesional
Documentos de Cultura
3.
4.
Dato de entrada
Resultado esperado
"valor"
"valor otrovalor"
"valor_otrovalor"
"-)valor:..=otrovalor?"
"__valor____otrovalor_"
"OtroValor"
"otrovalor"
"_un_valor_y_otro_valor_"
Est escrito con PHP, es muy rpido y est bien diseado internamente. Consta
icamente de un archivo, llamado lime.php, y no tiene ninguna dependencia.
include(dirname(__FILE__).'/../bootstrap/unit.php');
require_once(dirname(__FILE__).'/../../lib/strtolower.php');
// strtolower()
$t->diag('strtolower()');
$t->isa_ok(strtolower('Foo'), 'string',
'strtolower() returns a string');
$t->is(strtolower('FOO'), 'foo',
'strtolower() transforms the input to lowercase');
$t->is(strtolower('foo'), 'foo',
'strtolower() leaves lowercase characters unchanged');
$t->is(strtolower('12#?@~'), '12#?@~',
'strtolower() leaves non alphabetical characters unchanged');
$t->is(strtolower('FOO BAR'), 'foo bar',
'strtolower() leaves blanks alone');
$t->is(strtolower('FoO bAr'), 'foo bar',
'strtolower() deals with mixed case input');
$t->is(strtolower(''), 'foo',
'strtolower() transforms empty strings into foo');
1..7
# strtolower()
ok 1 - strtolower() returns a string
ok 2 - strtolower() transforms the input to lowercase
ok 3 - strtolower() leaves lowercase characters unchanged
ok 4 - strtolower() leaves non alphabetical characters unchanged
ok 5 - strtolower() leaves blanks alone
ok 6 - strtolower() deals with mixed case input
not ok 7 - strtolower() transforms empty strings into foo
#
#
#
got: ''
expected: 'foo'
include(dirname(__FILE__).'/../bootstrap/unit.php');
function lanza_una_excepcion()
{
throw new Exception('excepcin lanzada');
}
$t->diag('hola mundo');
$t->ok(1 == '1', 'el operador de igualdad ignora el tipo de la variable');
$t->is(1, '1', 'las cadenas se convierten en nmeros para realizar la comparacin');
$t->isnt(0, 1, '0 y 1 no son lo mismo');
$t->like('prueba01', '/prueba\d+/', 'prueba01 sigue el patrn para numerar las
pruebas');
$t->unlike('pruebas01', '/prueba\d+/', 'pruebas01 no sigue el patrn');
$t->cmp_ok(1, '<', 2, '1 es inferior a 2');
$t->cmp_ok(1, '!==', true, '1 y true no son exactamente lo mismo');
$t->isa_ok('valor', 'string', '\'valor\' es una cadena de texto');
$t->isa_ok(new miObjeto(), 'miObjeto', 'new crea un objeto de la clase correcta');
$t->can_ok(new miObjeto(), 'miMetodo', 'los objetos de la clase miObjeto tienen un
mtodo llamado miMetodo');
$array1 = array(1, 2, array(1 => 'valor', 'a' => '4'));
$t->is_deeply($array1, array(1, 2, array(1 => 'valor', 'a' => '4')),
'el primer array y el segundo array son iguales');
$t->include_ok('./nombreArchivo.php', 'el archivo nombreArchivo.php ha sido
incluido correctamente');
try
{
lanza_una_excepcion();
$t->fail('no debera ejecutarse ningn cdigo despus de lanzarse la excepcin');
}
catch (Exception $e)
{
if (!isset($variable))
{
$t->skip('saltamos una prueba para mantener el contador de pruebas correcto
para la condicin', 1);
}
else
{
$t->ok($variable, 'valor');
}
1..16
# hola mundo
ok 1 - el operador de igualdad ignora el tipo de la variable
ok 2 - las cadenas se convierten en nmeros para realizar la comparacin
ok 3 - 0 y 1 no son lo mismo
ok 4 - prueba01 sigue el patrn para numerar las pruebas
ok 5 - pruebas01 no sigue el patrn
ok 6 - 1 es inferior a 2
ok 7 - 1 y true no son exactamente lo mismo
ok 8 - 'valor' es una cadena de texto
ok 9 - new crea un objeto de la clase correcta
ok 10 - los objetos de la clase miObjeto tienen un mtodo llamado miMetodo
ok 11 - el primer array y el segundo array son iguales
not ok 12 - el archivo nombreArchivo.php ha sido incluido correctamente
#
#
El mtodo diag() no cuenta como una prueba. Se utiliza para mostrar mensajes,
de forma que la salida por pantalla est ms organizada y sea ms fcil de leer.
Por otra parte, los mtodos todo() yskip() cuentan como si fueran pruebas reales.
La combinacin pass()/fail() dentro de un bloquetry/catch cuenta como una sola
prueba.
Una estrategia de pruebas bien planificada requiere que se indique el nmero
esperado de pruebas. Indicar este nmero es una buena forma de validar los
propios archivos de pruebas, sobre todo en los casos ms complicados en los que
algunas pruebas se ejecutan dentro de condiciones y/o excepciones. Adems, si la
prueba falla en cualquier punto, es muy fcil de verlo porque el nmero de pruebas
realizadas no coincide con el nmero de pruebas esperadas.
El segundo parmetro del constructor del objeto lime_test indica el objeto que se
utiliza para mostrar los resultado. Se trata de un objeto que extiende la
clase lime_output. La mayora de las veces, como las pruebas se realizan en una
interfaz de comandos, la salida se construye mediante el objeto lime_output_color,
que muestra la salida coloreada en los sistemas que lo permiten.
15.2.4. La tarea test:unit
La tarea test:unit, que se utiliza para ejecutar las pruebas unitarias desde la lnea
de comandos, admite como argumento una serie de nombres de pruebas o un
patrn de nombre de archivos. El listado 15-5 muestra los detalles.
Listado 15-5 - Ejecutando las pruebas unitarias
// Estructura del directorio de pruebas
test/
unit/
miFuncionalTest.php
miSegundoFuncionalTest.php
otro/
nombreTest.php
## Ejecutar miFuncionalTest.php
## Ejecuta nombreTest.php
## Ejecuta todas las pruebas (de
include(dirname(__FILE__).'/../bootstrap/unit.php');
require_once($sf_symfony_lib_dir.'/util/sfToolkit.class.php');
// isPathAbsolute()
$t->diag('isPathAbsolute()');
$t->is(sfToolkit::isPathAbsolute('/test'), true,
'isPathAbsolute() returns true if path is absolute');
$t->is(sfToolkit::isPathAbsolute('\\test'), true,
'isPathAbsolute() returns true if path is absolute');
$t->is(sfToolkit::isPathAbsolute('C:\\test'), true,
Otra tcnica muy utilizada para evitar los problemas de la carga automtica de
clases es el uso destubs o clases falsas. Un stub es una implementacin
alternativa de una clase en la que los mtodos reales se sustituyen por datos
simples especialmente preparados. De esta forma, se emula el comportamiento de
la clase real y se reduce su tiempo de ejecucin. Los casos tpicos para
utilizarstubs son las conexiones con bases de datos y las interfaces de los
servicios web. En el listado 15-7, las pruebas unitarias para una API de un servicio
de mapas utilizan la clase WebService. En vez de ejecutar el mtodo fetch() real
de la clase del servicio web, la prueba utiliza un stub que devuelve datos de
prueba.
Listado 15-7 - Utilizando stubs en las pruebas unitarias
require_once(dirname(__FILE__).'/../../lib/WebService.class.php');
require_once(dirname(__FILE__).'/../../lib/MapAPI.class.php');
$t->is($miMapa->getMapSize(testWebService::fetch(), 100));
Los datos de prueba pueden ser ms complejos que una cadena de texto o la
llamada a un mtodo. Los datos de prueba complejos se suelen
denominar "fixtures". Para mejorar el cdigo de las pruebas unitarias, es
recomendable mantener los fixtures en archivos independientes, sobre todo si se
utilizan en ms de una prueba. Adems, Symfony es capaz de transformar un
archivo YAML en un array mediante el mtodo sfYAML::load(). De esta forma, en
vez de escribir arrays PHP muy grandes, los datos para las pruebas se pueden
guardar en archivos YAML, como en el listado 15-8.
Listado 15-8 - Usando archivos para los "fixtures" de las pruebas unitarias
// En fixtures.yml:
input: '/test'
output: true
comment: isPathAbsolute() returns true if path is absolute
input: '\\test'
output: true
comment: isPathAbsolute() returns true if path is absolute
input: 'C:\\test'
output: true
comment: isPathAbsolute() returns true if path is absolute
input: 'd:/test'
output: true
comment: isPathAbsolute() returns true if path is absolute
input: 'test'
output: false
comment: isPathAbsolute() returns false if path is relative
input: '../test'
output: false
comment: isPathAbsolute() returns false if path is relative
input: '..\\test'
output: false
comment: isPathAbsolute() returns false if path is relative
// En testTest.php
<?php
include(dirname(__FILE__).'/../bootstrap/unit.php');
require_once($sf_symfony_lib_dir.'/util/sfToolkit.class.php');
require_once($sf_symfony_lib_dir.'/yaml/sfYaml.class.php');
$testCases = sfYaml::load(dirname(__FILE__).'/fixtures.yml');
// isPathAbsolute()
$t->diag('isPathAbsolute()');
foreach ($testCases as $case)
{
$t->is(sfToolkit::isPathAbsolute($case['input']), $case['output'],$case['comment']);
}
include(dirname(__FILE__).'/../bootstrap/unit.php');
new
sfDatabaseManager(ProjectConfiguration::getApplicationConfiguration('frontend',
'test', true));
$loader = new sfPropelData();
$loader->loadData(sfConfig::get('sf_data_dir').'/fixtures');
$t->diag('->retrieveByUsername()');
$user = UserPeer::retrieveByUsername('fabien');
$t->is($user->getLastName(), 'Potencier', '->retrieveByUsername() returns the
User for the given username');
funciona de prueba para este mdulo. La prueba realiza una peticin a la accin
por defecto del mdulo y comprueba el cdigo de estado de la respuesta, el
mdulo y la accin calculados por el sistema de enrutamiento y la presencia de
una frase especfica en el contenido de la respuesta. Si el mdulo se llama foobar,
el archivofoobarActionsTest.php generado es similar al del listado 15-9.
Listado 15-9 - Prueba funcional por defecto para un mdulo nuevo,
entests/functional/frontend/foobarActionsTest.php
<?php
include(dirname(__FILE__).'/../../bootstrap/functional.php');
$browser->
get('/foobar/index')->
isStatusCode(200)->
isRequestParameter('module', 'foobar')->
isRequestParameter('action', 'index')->
checkResponseElement('body', '!/This is a temporary page/')
;
# get /comment/index
ok 1 - status code is 200
ok 2 - request parameter module is foobar
ok 3 - request parameter action is index
not ok 4 - response selector body does not match regex /This is a temporary page/
# Looks like you failed 1 tests of 4.
1..4
$b->get('/foobar/show/id/1');
// Peticin GET
// Peticin POST
$b->get('/');
$b->get('/foobar/show/id/1');
$b->back();
$b->forward();
$b->reload();
$b->click('go');
Entre las interacciones que ms se deben probar, las de los formularios son
probablemente las ms necesarias. Symfony dispone de 3 formas de probar la
introduccin de datos en los formularios y su envo. Se puede crear una peticin
POST con los parmetros que se quieren enviar, se puede llamar al
mtodo click() con los parmetros del formulario en un array o se pueden rellenar
los campos del formulario de uno en uno y despus pulsar sobre el botn de
envo. En cualquiera de los 3 casos, la peticin POST resultante es la misma. El
listado 15-13 muestra un ejemplo.
Listado 15-13 - Simulando el envo de un formulario con datos mediante el
objeto sfTestBrowser
// Plantilla de ejemplo en modules/foobar/templates/editSuccess.php
<?php echo form_tag('foobar/update') ?>
<?php echo input_hidden_tag('id', $sf_params->get('id')) ?>
<?php echo input_tag('name', 'foo') ?>
<?php echo submit_tag('go') ?>
<?php echo textarea('text1', 'foo') ?>
<?php echo textarea('text2', 'bar') ?>
</form>
Si una accin finaliza con una redireccin ( redirect()), el navegador para pruebas
no sigue automticamente la redireccin, sino que se debe seguir manualmente
mediante followRedirect(), como se muestra en el listado 15-14.
Listado 15-14 - El navegador para pruebas no sigue automticamente las
redirecciones
// Accin de ejemplo en modules/foobar/actions/actions.class.php
public function executeUpdate($peticion)
{
// ...
$this->redirect('foobar/show?id='.$peticion->getParameter('id'));
}
Existe un ltimo mtodo muy til para la navegacin: restart(), que inicializa el
historial de navegacin, la sesin y las cookies, es decir, como si se reiniciara el
navegador.
Una vez realizada la primera peticin, el objeto sfTestBrowser dispone de acceso
directo a los objetos de la peticin, del contexto y de la respuesta. De esta forma,
se pueden probar muchas cosas diferentes, desde el contenido textual de las
pginas a las cabeceras de la respuesta, pasando por los parmetros de la
peticin y la configuracin:
$peticion = $b->getRequest();
$contexto = $b->getContext();
$respuesta = $b->getResponse();
setField('name', 'dummy')->
click('go');
$content = $b->getResponse()->getContent();
// ...
El objeto sfBrowser es muy til para ejecutar scripts programados, como por
ejemplo para navegar por una serie de pginas para generar la cache de cada
pgina (el Captulo 18 muestra un ejemplo detallado).
15.3.3. Utilizando asertos
$b->test()->like($response->getContent(), '/edit/');
// Cookie enviada
$cookies = $response->getCookies();
$b->test()->is($cookies['foo'], 'foo=bar');
// Cookie recibida
En la prctica, los mtodos especiales del listado 15-17 cubren la mayor parte de
las pruebas habituales, por lo que raramente es necesario utilizar el
mtodo test() del objeto sfTestBrowser.
El listado 15-14 demuestra que sfTestBrowser no sigue directamente las
redirecciones. La ventaja de este comportamiento es que se pueden probar las
propias redirecciones. El listado 15-18 muestra cmo probar la respuesta del
listado 15-14.
Listado 15-18 - Probando las redirecciones con sfTestBrowser
$b = new sfTestBrowser();
$b->
get('/foobar/edit/id/1')->
click('go', array('name' => 'dummy'))->
isStatusCode(200)->
isRequestParameter('module', 'foobar')->
isRequestParameter('action', 'update')->
isRedirected()->
followRedirect()->
isStatusCode(200)->
isRequestParameter('module', 'foobar')->
isRequestParameter('action', 'show');
Muchas pruebas funcionales validan que una pgina sea correcta comprobando
que un determinado texto se encuentre en el contenido de la respuesta. Utilizando
el mtodo responseContains() y las expresiones regulares, es posible comprobar
que existe un determinado texto, los atributos de una etiqueta o sus valores. Pero
si lo que se quiere probar se encuentra en lo ms profundo del rbol DOM del
contenido de la respuesta, la solucin de las expresiones regulares es demasiado
compleja.
Este es el motivo por el que el objeto sfTestBrowser dispone de un mtodo
llamado getResponseDom(). El mtodo devuelve un objeto DOM de libXML2, que
es mucho ms fcil de procesar que el texto simple. El listado 15-19 muestra un
ejemplo de uso de este mtodo.
Listado 15-19 - El navegador para pruebas devuelve el contenido de la
respuesta como un objeto DOM
$b = new sfTestBrowser();
$b->get('/foobar/edit/id/1');
$dom = $b->getResponseDom();
$b->test()->is($dom->getElementsByTagName('input')->item(1)>getAttribute('type'),'text');
Sin embargo, procesar un documento HTML con los mtodos DOM de PHP no es
lo suficientemente rpido y sencillo. Por su parte, los selectores utilizados en las
hojas de estilos CSS son una forma aun ms potente de obtener los elementos de
un documento HTML. Symfony incluye una herramienta
llamada sfDomCssSelector, cuyo constructor espera un documento DOM como
argumento. Esta utilidad dispone de un mtodo llamado getTexts() que devuelve
$b->initialize();
$b->get('/foobar/edit?id=1')->
checkResponseElement('form input', true, array('count' => 3));
isRequestParameter('module', 'foobar')->
isRequestParameter('action', 'update')->
throwsException()->
excepcin
web_debug:
of
no_script_name:
etag:
of
of
## Ejecutar todas las pruebas funcionales cuyos nombres cumplan con el patrn
indicado
> php symfony test:functional frontend my*
miEscenarioTest.php
backend/
miOtroEscenarioTest.php
En las pruebas unitarias, una buena prctica consiste en agrupar las pruebas
segn la funcin o mtodo y comenzar cada grupo de pruebas con una llamada al
mtodo diag(). Los mensajes de cada prueba unitaria deberan mostrar el nombre
de la funcin o mtodo que se prueba, seguido de un verbo y una propiedad, de
forma que el resultado que se muestra parezca una frase que describe una
propiedad de un objeto. El listado 15-30 muestra un ejemplo.
Listado 15-30 - Ejemplo de recomendaciones para las pruebas unitarias
// srttolower()
$t->diag('strtolower()');
$t->isa_ok(strtolower('Foo'), 'string', 'strtolower() devuelve una cadena de texto');
$t->is(strtolower('FOO'), 'foo', 'strtolower() transforma la entrada en minsculas');
# strtolower()
ok 1 - strtolower() devuelve una cadena de texto
ok 2 - strtolower() transforma la entrada en minsculas
Las pruebas funcionales deberan agruparse por pgina y deberan comenzar con
una peticin. El listado 15-31 muestra un ejemplo de esta prctica.
Listado 15-31 - Ejemplo de recomendaciones para las pruebas funcionales
$browser->
get('/foobar/index')->
isStatusCode(200)->
isRequestParameter('module', 'foobar')->
isRequestParameter('action', 'index')->
checkResponseElement('body', '/foobar/')
;
# get /comment/index
ok 1 - status code is 200
ok 2 - request parameter module is foobar
ok 3 - request parameter action is index
ok 4 - response selector body matches regex /foobar/
unit/miFuncionTest.php.................ok
unit/miSegundaFuncionTest.php..........ok
unit/foo/barTest.php...................not ok
Failed Test
-----------------------------------------------------------------unit/foo/barTest.php
2 62 63
Failed 1/3 test scripts, 66.66% okay. 2/53 subtests failed, 96.22% okay.
Antes de comenzar las pruebas, se suele cargar la base de datos con datos de
prueba, tambin llamados fixtures. El objeto sfPropelData permite realizar esta
carga. No solamente es posible utilizar este objeto para cargar datos a partir de un
archivo (como con la tarea propel:data-load) sino que tambin es posible hacerlo
desde un array, como muestra el listado 15-35.
Listado 15-35 - Cargando datos en la base de datos desde una prueba
$data = new sfPropelData();
'body'
=> array(
=> 'foo foo title',
=> 'bar bar body',
Una vez cargados los datos, se pueden utilizar los objetos Propel necesarios como
en cualquier aplicacin normal. Las pruebas unitarias deben incluir los archivos
correspondientes a esos objetos (se puede utilizar la clase sfSimpleAutoload para
automatizar la carga, como se explic en la seccin anterior "Stubs, Fixtures y
carga automtica de clases"). Los objetos de Propel se cargan automticamente
en las pruebas funcionales.
15.5.3. Probando la cache
include(dirname(__FILE__).'/../../bootstrap/functional.php');
$b->get('/mymodule');
$b->isCached(true);
<td>/frontend_test.php/</td>
<tr><td>clickAndWait</td>
<td> </td></tr>
<td>link=pinchame</td>
Cada caso de prueba consiste en una pgina HTML con una tabla de 3 columnas:
comando, destino y valor. No obstante, no todos los comandos indican un valor. En
caso de que no se utilice un valor, es recomendable incluir el valor en esa
columna (para que la tabla se vea mejor). El sitio web de Selenium dispone de la
lista completa de comandos que se pueden utilizar.
Tambin es necesario aadir esta prueba al conjunto completo de pruebas,
insertando una nueva lnea en la tabla del archivo TestSuite.html del mismo
directorio. El listado 15-38 muestra cmo hacerlo.
Listado 15-38 - Aadiendo un archivo de pruebas al conjunto de pruebas,
enweb/selenium/test/TestSuite.html
...
<tr><td><a href='./testIndex.html'>Mi primera prueba</a></td></tr>
...
solo navegador, se puede lanzar esa prueba sobre todos los navegadores y
comprobar su funcionamiento.
Como las pruebas de Selenium se crean con HTML, acaba siendo muy aburrido
escribir todo ese cdigo HTML. Afortunadamente, existe una extensin de
Selenium para Firefox (http://seleniumrecorder.mozdev.org/) que
permite grabar todos los movimientos y acciones realizadas sobre una pgina y
guardarlos como una prueba. Mientras se graba una sesin de navegacin, se
pueden aadir pruebas de tipo asertos pulsando el botn derecho sobre la ventana
del navegador y seleccionando la opcin apropiada del menn "Append Selenium
Command".
Una vez realizados todos los movimientos y aadidos todos los comandos, se
pueden guardar en un archivo HTML para aadirlo al conjunto de pruebas. La
extensin de Firefox incluso permite ejecutar las pruebas de Selenium que se han
creado con la extensin.
15.6. Resumen
La automatizacin de pruebas abarca tanto las pruebas unitarias (que validan
mtodos o funciones) como las pruebas funcionales (que validan caractersticas
completas de la aplicacin). Symfony utiliza el framework de pruebas Lime para
las pruebas unitarias y proporciona la clase sfTestBrowser para las pruebas
funcionales. En ambos casos, se dispone de mtodos para realizar todo tipo de
asertos, desde los ms sencillos hasta los ms complejos, como por ejemplo los
que se realizan mediante los selectores de CSS. La lnea de comandos de
Symfony permite ejecutar las pruebas de una en una (mediante las
tareas test:unit y test:functional) o en grupo (mediante la tarea test:all). En lo que
respecta a los datos, las pruebas automatizadas utilizan stubs (clases falsas)
y fixtures (datos de prueba complejos) y Symfony simplifica su uso desde las
pruebas unitarias.
Si se definen las suficientes pruebas unitarias como para probar la mayor parte de
una aplicacin (quizs aplicando la metodologa TDD), es mucho ms seguro
refactorizar el cdigo de la aplicacin y aadir nuevas caractersticas. Incluso, en
Imprimir
4 Comments
Contents
1.
2.
3.
4.
5.
Introduccin
Pruebas utilizando objetos simulados (mock)
Utilizacin de stub, mock y proxy
Conclusiones
Referencias
La primera parte de esta serie de artculos realiza una introduccin a las Pruebas
Unitarias, repasa sus caractersticas y ventajas, para finalizar con la descripcin de los
diferentes tipos de objetos mock y la forma de utilizarlos.
Introduccin
Todos los programadores saben que deben realizar pruebas a su cdigo, pocos lo hacen
de manera proactiva, la respuesta generalizada al por qu no? es no tengo
tiempo.
Este apuro se convierte en un crculo vicioso. Cuanta ms presin se siente, menos
pruebas se realizan. Cuantas menos pruebas se realizan, menos productivo se es y el
cdigo se vuelve menos estable. Cuanto menos productivo y preciso se es, ms presin
se siente.
Ventajas
Las pruebas unitarias buscan aislar cada parte del programa y mostrar que las partes
individuales son correctas, proporcionando cinco ventajas bsicas:
Consideraciones
Como en la adopcin de cualquier otra disciplina, la incoporacin de pruebas unitarias
no est exenta de problemas o limitaciones, a continuacin se enumeran algunas
consideraciones a tener en cuenta:
Unidad Colaborador
Unidad Mock
Objetos stub
Un stub es un objeto que implementa una interface de un componente, pero en lugar
de retornar lo que el componente devolvera, el stub puede ser configurado para
retornar un valor que se ajuste a lo que la prueba unitaria intenta probar.
Utilizando este tipo de objetos se puede probar si una unidad es capaz de manejar
diferentes valores devueltos por el colaborador. Esto se puede expresar de la
siguiente manera:
El primer paso de la prueba unitaria es crear el objeto stub y configurar los valores de
retorno (1). Luego se crea la unidad y se le setea el stub en lugar
del colaborador real (2). Por ltimo se verifica el resultado de la llamada a
la unidad (3).
4
5
6
7
8
9
10
Objetos mock
Un mock es como un stub, que adems permite determinar qu mtodos fueron
llamados durante la prueba. Utilizando un mock se puede probar tanto si los valores
devueltos por la unidad son los correctos, como as tambin si la unidad est
utilizando de forma correcta al colaborador.
Por ejemplo, no se puede ver a partir del valor devuelto desde el objeto DAO si la
informacin que fue leda desde la base de datos se realiz a travs de un Statement o
de un PreparedStatement. Tampoco se puede determinar si el mtodo .close() fue
invocado antes de devolver el valor. Esto es posible con mock, estos permiten probar
la integracin completa de la unidad con el colaborador.
El primer paso de la prueba unitaria es crear el objeto mock y configurar los valores de
retorno (1). Luego la prueba unitaria llama a la unidad que llama al mock (2). Por
ltimo se verifica el resultado de la llamada a launidad (3). La prueba unitaria
tambin realiza verificaciones con respecto a los mtodos que fueron llamados en
el mock (4).
4
5
7
8
calculadora.setDao(mockGenericDao);
9
10
11
verify at least one call of mockGenericDao.getPrimerValor();
12
13
Objetos proxy
Los proxies son objetos mock que delegan las llamadas a los mtodos en el
objeto colaborador real, pero contina registrando internamente qu mtodos fueron
llamados en el proxy. Los proxies permiten hacer pruebas mock con los colaboradores
reales:
Conclusiones
En este primer artculo de la serie dedicada a las Pruebas Unitarias hemos realizado
una introduccin al tema, realizamos una descripcin de las ventajas que supone su
adopcin, e intentamos incorporar informacin de utilidad verificada durante la
implementacin de la disciplina dentro de MicroGestion.
La introduccin nos sirvi como base para describir de manera terica la utilizacin de
objetos mock en los casos que es necesario simular los objetos utilizados por las clases
cuyo funcionamiento necesitamos verificar.
En el prximo artculo describiremos las estrategias para realizar pruebas en diferentes
escenarios.