Buena metodología para test unitario.

136 views
Skip to first unread message

Pablo Braulio

unread,
Aug 1, 2011, 9:51:58 AM8/1/11
to Lista Agile-spain
Hola a todos.

Estoy tratando de crear un test unitario a un método que hace un
insert en la BD.
Me gustaría saber cual es vuestra opinión respecto al uso de esto.

¿Usáis algún tipo de assert para saber si el método se ejecuta
correctamente?, o ¿por otro lado hacéis un select para comprobar que
dicho valor se ha insertado?.

Gracias.
--
--
Saludos cordiales.
Pablo.

Si lo reenvías, ten la precaución de borrar los datos de procedencia que
encabezarían tu reenvío – empezando por mi dirección de correo
electrónico - . Coloca siempre las direcciones de tus contactos en el
campo <CCO> para que viajen discretas, no en el campo <Para> ni en
el<CC>. De esa forma nadie que lo reciba tendrá constancia de las señas
de los demás destinatarios a los que también se remite. Todo ello a fin
de evitar que nadie se aproveche de todas las direcciones que se van
acumulando al pasar de buzón a buzón para el lanzamiento de correo
basura y otras indeseadas lindezas. Aparte claro está de garantizar la
privacidad.

Alfredo Casado

unread,
Aug 1, 2011, 10:41:29 AM8/1/11
to agile...@googlegroups.com
Las dos opciones que tienes son:

Probar el comportamiento  "el registro X se inserta en la base de datos correctamente" lo suyo es que para verificarlo lo hagas con un Select (sin poner el select a pelo en el código del test, con algún matcher o algo que deje el test legible).

La otra posibilidad es mockear el driver de la bd bd y probar el comportamiento "mi clase X llama con los parametros correctos y en el orden correcto a los métodos que ofrece el driver de BD", este comportamiento en mi opinión no aporta mucho valor y además acopla tu código con los test demasiado, en general no es buena idea mockear interfaces que no sean tuyas (la del driver de bd por ejemplo).

Intenta pensar en términos de comportamientos en lugar de en métodos, sólo con este cambio encontraras respuesta a muchas dudas que te van surgiendo al hacer TDD/BDD.


--
Has recibido este mensaje porque estás suscrito al grupo "agile-spain" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a agile...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a agile-spain...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/agile-spain?hl=es.


Pablo Braulio

unread,
Aug 1, 2011, 10:44:31 AM8/1/11
to agile...@googlegroups.com
De acuerdo. Muchas gracias.

El día 1 de agosto de 2011 16:41, Alfredo Casado
<casado....@gmail.com> escribió:

Sebastian Hermida

unread,
Aug 1, 2011, 2:59:23 PM8/1/11
to agile-spain
Cuando escribo tests unitarios que tocan la base de datos, suelo
mockear la llamadas que tocan los datos.

La verificacion de que todo ha funcionado, lo hago con acceptance
testing, que suelen ser "end to end" y cerca del equivalente a una
historia de usuario.

La razon por la que mockeo con test unitarios, es que quiero que
corran muy rapido y que se puedan ejecutar sin connexiones a otros
servidores. Que pueda estar en el tren con el portatil y correr todos
mis tests.

Saludos,
Sebastian

Jesús Jiménez

unread,
Aug 1, 2011, 3:04:27 PM8/1/11
to agile...@googlegroups.com
El 1 de agosto de 2011 20:59, Sebastian Hermida <seb...@gmail.com> escribió:

La razon por la que mockeo con test unitarios, es que quiero que
corran muy rapido y que se puedan ejecutar sin connexiones a otros
servidores. Que pueda estar en el tren con el portatil y correr todos
mis tests.


¿Y por qué no usar una BD en memoria para esto?  

Sebastian Hermida

unread,
Aug 1, 2011, 3:51:21 PM8/1/11
to agile-spain
On Aug 1, 9:04 pm, Jesús Jiménez <jjball...@gmail.com> wrote:
> El 1 de agosto de 2011 20:59, Sebastian Hermida <seba...@gmail.com>escribió:
>
>
>
> > La razon por la que mockeo con test unitarios, es que quiero que
> > corran muy rapido y que se puedan ejecutar sin connexiones a otros
> > servidores. Que pueda estar en el tren con el portatil y correr todos
> > mis tests.
>
> ¿Y por qué no usar una BD en memoria para esto?

Si, una base de datos en memoria vale para correr los tests
desconectados de la red, pero por mi experiencia, siguen siendo lentos
y no sustituyen el acceptance testing. Probamos durante un tiempo pero
perdimos el interes en escribirlos. Usamos HSQLDB para este
experimento.

Tambien probamos con dbUnit, y hasta escribimos nuestra propia version
que te dejaba relajar las retricciones de los "Foreign Keys". Pero aun
asi, nunca fueron considerados test unitarios. Eran considerados tests
de intergracion.

Grails tiene una filosofia parecida de separar distintos tipos de
tests.

Los unitarios no pueden acceder a la base de datos.
Los de integracion acceden a la base de datos en memoria.
Y los funcionales correr todo el "stack".

Alfredo Casado

unread,
Aug 1, 2011, 4:00:05 PM8/1/11
to agile...@googlegroups.com

Personalmente prefiero hacer test de integracion que se ejecutan razonablemente rapido para guiar la esritura del código de acceso a datos. Por ejemplo si escribo mal una query es mucho más rápido detectarlo mediante estos test que mediante test  end to end.

Claro que puede dependender de muchas cosas, como si usas un motor ORM o no. Lo que desde luego no le recomendaría ni a mi peor enemigo es mockear APIs como JDBC jeje.

Enrique Comba Riepenhausen

unread,
Aug 1, 2011, 4:08:11 PM8/1/11
to agile...@googlegroups.com
Yo personalmente creo "doubles" para todo lo que no sea la clase bajo test en un test unitario. 

¿Porque? Simplemente porque creo código mucho mas solido y me ayuda a diseñar mi código de forma segura.

¿Porque no escribo tests unitarios que acceden la BBD? Simplemente porque quiero testar mi código y no el código del proveedor del API que estoy utilizando para acceder la BBD.

Al igual que dice Sebastian, cuando escribo mis tests funcionales es cuando hago tests "end to end".

Contestando a Alfredo, el test funcional es el primero que escribo y una vez que me satisface el código que he escrito (gracias a mis tests unitarios) lanzo mis tests de aceptación (cosa que ocurre cada 10 - 15 min max).

Un saludo,

-- 
Enrique Comba Riepenhausen
.:: Software Craftsman ::.

Skype:  ecomba

Alfredo Casado

unread,
Aug 1, 2011, 5:22:59 PM8/1/11
to agile...@googlegroups.com
¿Porque no escribo tests unitarios que acceden la BBD? Simplemente porque quiero testar mi código y no el código del proveedor del API que estoy utilizando para acceder la BBD.

En realidad lo que yo quiero probar no es logicamente que el API de acceso a bd funciona, lo que quiero probar es que mi código interactua correctamente con ese api. Esto no es un test unitario, es un test de integración, pero vamos que me da igual la etiqueta del test (unitario, funcional de integración...) lo que me interesa es que comportamiento estoy probando, y en mi caso el comportamiento a probar es que mi código interactua adecuadamente con la base de datos, tenemos además que soportar varias al mismo tiempo y por desgracia no todas se comportan exactamente igual.

Por ejemplo, si tengo una clase PersonaDAO o PersonaRepository o PersonaActiveRecord o cual sea el patrón de acceso a datos que uses, lo que no voy ha hacer es probar esa clase mockeando las llamadas a JDBC (por poner el caso de java) por varias razones:

- JDBC es duro de mockear de narices :P
- Con esto sólo compruebo que mi código llama en el orden que yo creo correcto al API de JDBC, no estoy comprobando si funciona o no para otras bd's ni tampoco estoy comprobando si ese orden que yo creo correcto es realmente correcto.

Por supuesto el código que use el PersonaX lo probaría mockeando esta clase. Otra opción es no probar en absoluto estas clases DAO o similares (quizas por que uses algún framework que las genere con algún tipo de magia) pero en nuestro caso no utilizamos ningún framework de acceso a datos más alla del uso puro y duro de jdbc y algunas clases de conveniencia propias. Por esto a veces, en función de la dificultad que tengan estas clases de acceso a datos (que no siempre son sólo un crud y a veces hay alguna consulta o se busca un comportamiento de la bd más complejo) las pruebo o no las prueba y simplemente tengo feedback de que están bien cuando ejecuto el test funcional. Aqui también depende de como sean esos test funcionales, si son puramente end-to-end desde el ui hasta la bd no me gusta demasiado sólo tener feedback de que he escrito bien mi código de acceso a datos con estos test porque por lo general ofrecen información que puede no ser fácil de interpretar acerca del motivo del fallo (esto también dependerá del tipo de UI o de tecnología que uses para estos test). En nuestro caso a veces los test funcionales son simples test con JUNIT porque hacemos un API que es parte de lo que entregamos a cliente (otros desarrolladores), en esto caso son test sencillos que se ejecutan razonablemente rápido y que ofrecen buena información cuando fallan. 

Yo creo que como siempre las cosas dependen de muchos factores como la tecnología que uses, el tipo de proyecto etc,etc. Al final todo son herramientas, los mocks, las utilidades para testing de base de datos etc,etc que tenemos que tener todas bien asimiladas para usarlas como mejor convenga según nuestro contexto y nuestro criterio, que muchas veces no habla de ciertas elecciones que toma teniendo en cuenta solo su contexto como si fueran una regla general, y por lo general las cosas son más complicadas. 

Eso si, ni robert martin personificado me convence de mockear JDBC, antes me quito la pulsera verde :P 

Carlos Ble

unread,
Aug 1, 2011, 6:14:20 PM8/1/11
to agile-spain
Hola,
Quizas te ayude pensar que un test que accede a BD NO es unitario,
porque no es rapido ni repetible ;-)

Saludos

Jesús Jiménez

unread,
Aug 1, 2011, 6:40:00 PM8/1/11
to agile...@googlegroups.com

Hombre, repetibles deberían ser todos los test, sean del tipo que sean, porque sino el señor Jenkins se me enfadaría aleatoriamente.

Alfredo Casado

unread,
Aug 1, 2011, 7:15:29 PM8/1/11
to agile...@googlegroups.com
Pues no creáis que a veces es tan facil esa distinción entre test unitario/integración/funcional. Un ejemplo, si dentro de una clase A utilizo el soporte del lenguaje (o de las librerías core del lenguaje) para por ejemplo trabajar con expresiones regulares ¿ podríamos considerar esto un test unitario si no mockeamos el uso de este motor de expresiones regulares?. Entonces si dentro de una clase A utilizo un api que me da acceso a un repositorio de datos en memoria (no hay un segundo sistema con el que me integre como un servidor de base de datos) ¿que diferencia existe entre el motor de expresiones regulares y un motor de acceso a datos en memoria para que un test le denominemos unitario y al otro no?.

Podríamos discutir sobre esto, ¿pero pa que?, ¿que importancia tiene?, por eso decía que mejor que nos fijemos en que comportamiento estamos implementando, y por supuesto también en características como la rapidez del test o la repetibilidad, y usemos las herramientas que mejor se adapten según el caso. No siempre las distinciones son tan claras ni se pueden poner reglas inamovibles.

alberto

unread,
Aug 1, 2011, 7:39:50 PM8/1/11
to agile...@googlegroups.com
Totalmente de acuerdo con Carlos. Si usas un contexto externo (bbdd, ficheros, ws,..) y que pase tu test o no depende de que hayas configurado de cierta forma el mismo, eso no es un test unitario, por definición (al menos la que manejamos Carlos y yo :D).

2011/8/2 Jesús Jiménez <jjba...@gmail.com>

alberto

unread,
Aug 1, 2011, 7:45:22 PM8/1/11
to agile...@googlegroups.com
En el caso de la bbdd, sigue sin ser unitario, EMHO. Para que pasen los test de bbdd necesitas prepopularla (¿poblarla?) con unos registros concretos, en el caso de la expresión regular no tienes que configurar nada.

2011/8/2 Alfredo Casado <casado....@gmail.com>

Pablo Braulio

unread,
Aug 2, 2011, 3:14:22 AM8/2/11
to agile...@googlegroups.com
Vaya, menudo debate.

Da gusto.

Pablo Braulio

unread,
Aug 2, 2011, 3:15:45 AM8/2/11
to agile...@googlegroups.com
Una duda de neofito. ¿Que es Mockear?.

Jesús Jiménez

unread,
Aug 2, 2011, 3:25:50 AM8/2/11
to agile...@googlegroups.com
Básicamente es desarrollar con Mocks (http://en.wikipedia.org/wiki/Mock_object)

Creo que lo explica mejor Alfredo de lo que podría hacerlo yo:

Muchas veces con mockear se refiere a trabajar con los diferentes tipos de dobles, no sólo con mocks, sino también con spies y stubs, pero se generaliza diciendo mockear.

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 3:54:22 AM8/2/11
to agile...@googlegroups.com
On Aug 1, 2011, at 11:22 PM, Alfredo Casado wrote:
Eso si, ni robert martin personificado me convence de mockear JDBC, antes me quito la pulsera verde :P 

Tampoco es para tanto (ejemplo con mockito):

java.sql.Statement statement = mock(java.sql.Statement.class)
when(statement.exequteQuery(query)).thenReturn(mock(ResultSet.class))

Lo que nos interesa no es como funciona JDBC si no que responde con lo que queremos realmente cuando hacemos peticiones a la BBD.

Un saludo,

Enrique

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 3:54:30 AM8/2/11
to agile...@googlegroups.com
On Aug 2, 2011, at 1:15 AM, Alfredo Casado wrote:

Pues no creáis que a veces es tan facil esa distinción entre test unitario/integración/funcional. Un ejemplo, si dentro de una clase A utilizo el soporte del lenguaje (o de las librerías core del lenguaje) para por ejemplo trabajar con expresiones regulares ¿ podríamos considerar esto un test unitario si no mockeamos el uso de este motor de expresiones regulares?. Entonces si dentro de una clase A utilizo un api que me da acceso a un repositorio de datos en memoria (no hay un segundo sistema con el que me integre como un servidor de base de datos) ¿que diferencia existe entre el motor de expresiones regulares y un motor de acceso a datos en memoria para que un test le denominemos unitario y al otro no?.

Si piensas que tus clases mayormente son inmutables e injectas las dependencias de las mismas no deberías encontrarte con esas distinciones.

De hecho si tu clase en cuestión depende de un motor de expresiones regulares (como en el caso de Java) seria mas limpio extraer la funcionalidad de esa expresion a su propia clase y testarla por separado.

Una clase debería estar especializada en una cosa única, y un método debería hacer una única cosa. Si tu método hace mas de una cosa es señal de que deberías extraer esa funcionalidad a otros sitios (p.eje. clases).

Podríamos discutir sobre esto, ¿pero pa que?, ¿que importancia tiene?, por eso decía que mejor que nos fijemos en que comportamiento estamos implementando, y por supuesto también en características como la rapidez del test o la repetibilidad, y usemos las herramientas que mejor se adapten según el caso. No siempre las distinciones son tan claras ni se pueden poner reglas inamovibles.

No, las reglas no son inamovibles, pero si no sabes utilizar las reglas no sabes cuando ignorarlas y porque.

Un saludo,

Enrique

Alfredo Casado

unread,
Aug 2, 2011, 4:21:47 AM8/2/11
to agile...@googlegroups.com
De hecho si tu clase en cuestión depende de un motor de expresiones regulares (como en el caso de Java) seria mas limpio extraer la funcionalidad de esa expresión a su propia clase y testarla por separado.

Supongamos que hago eso (que me parece perfecto), entonces tengo una clase donde su única responsabilidad es encapsular el motor de ER y ofrecer un interfaz que me guste más o encaje más con mi negocio al resto de mis clases, por ejemplo supongamos que tengo una clase para "sanear" cadenas eliminando ciertos caracteres especiales:

public class Saneador {

   public String limpiaYDaEsplendor(final String cadenaSucia) {
       
        return  motorDeJavaDeER.aplicarER("una ER que sirva para quitar caracteres especiales");
   }

}

Esta clase no tiene ninguna responsabilidad más que sanear una cadena, incluso podría hacerlo sin usar ER. LLegados a este punto ¿tiene realmente interés mockear el motorDeJavaDeER?. No quiero esperar a un test funcional para saber que escribo bien la expresión regular y que he llamado en el orden correcto a los métodos/objetos que tengo que usar el motor de ER, como soy muy olvidadizo nunca me acuerdo de como se hacen estas cosas y hacer un test con mocks primero que se limite a comprobar que llamo al motor con la ER que yo creo que es la correcta no me esta aportando en realidad gran cosa.

Pues con JDBC o acceso a datos yo lo veo muy similar, si tengo clases cuya única responsabilidad es hacer una query al motor de bd recoger los resultados y meterlos en un Value Object ¿le veis realmente valor a mockear las llamadas a JDBC para escribir esta clase?. 

¿las collections las mockeais también? :P

Leo Antoli

unread,
Aug 2, 2011, 4:39:06 AM8/2/11
to agile...@googlegroups.com
Me están resultando muy interesante las conversaciones de este hilo.

Creo que yo estoy más acostumbrado a pensar como Alfredo, diría que a estilo "clasicista" en que me importa más como se comporta mi clase que lo que hace por dentro. Es cierto que problabmente no se pueden llamar tests unitarios estrictamente. Un problema que me suelo encontrar con esta aproximación es que pruebas una clase con sus colaboradores, luego pruebas una clase que tiene un colaborador que tiene otro, etc. Al final no está mal porque cada capa prueba todas las anteriores y da bastante confianza en el código, pero es verdad que hay potencialmente duplicidad de funcionalidad probada y salen tests más lentos de ejecutar (aunque se pueden hacer cosas como mockear las capas bajas de acceso a BD o sistemas externos en general).

Enrique creo que es más "behaviourist" y le interesa más comprobar que una clase llama como él cree a sus colaboradores, más que cómo se comporte de verdad la clase una vez decididos sus colaboradores. Puede que yo crea que estoy llamando en secuencia correcta a los colaboradores y no sea así, esto se intentará detectar en tests funcionales. 

Creo que lo que dice Enrique tiene bastante sentido y cada vez intento pensar más de esa forma, aunque a día de hoy suelo hacer más lo que dice Alfredo.

Saludos,
Leo



2011/8/2 Alfredo Casado <casado....@gmail.com>

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 4:48:22 AM8/2/11
to agile...@googlegroups.com
On Aug 2, 2011, at 10:21 AM, Alfredo Casado wrote:

De hecho si tu clase en cuestión depende de un motor de expresiones regulares (como en el caso de Java) seria mas limpio extraer la funcionalidad de esa expresión a su propia clase y testarla por separado.

Supongamos que hago eso (que me parece perfecto), entonces tengo una clase donde su única responsabilidad es encapsular el motor de ER y ofrecer un interfaz que me guste más o encaje más con mi negocio al resto de mis clases, por ejemplo supongamos que tengo una clase para "sanear" cadenas eliminando ciertos caracteres especiales:

public class Saneador {

   public String limpiaYDaEsplendor(final String cadenaSucia) {
       
        return  motorDeJavaDeER.aplicarER("una ER que sirva para quitar caracteres especiales");
   }

}

Esta clase no tiene ninguna responsabilidad más que sanear una cadena, incluso podría hacerlo sin usar ER. LLegados a este punto ¿tiene realmente interés mockear el motorDeJavaDeER?.

Si

No quiero esperar a un test funcional para saber que escribo bien la expresión regular y que he llamado en el orden correcto a los métodos/objetos que tengo que usar el motor de ER, como soy muy olvidadizo nunca me acuerdo de como se hacen estas cosas y hacer un test con mocks primero que se limite a comprobar que llamo al motor con la ER que yo creo que es la correcta no me esta aportando en realidad gran cosa.

De hecho tendrías tests unitarios para tu Saneador que asegurarían que la clase Saneador funciona como es debido.

En los tests funcionales no escribirías ningún double ya que estas testando el comportamiento de la aplicación en su totalidad (i.e. con todos los componentes que la componen).
 
Pues con JDBC o acceso a datos yo lo veo muy similar, si tengo clases cuya única responsabilidad es hacer una query al motor de bd recoger los resultados y meterlos en un Value Object ¿le veis realmente valor a mockear las llamadas a JDBC para escribir esta clase?.

Si.

 ¿las collections las mockeais también? :P

No, aunque hay casos en los que si (sobretodo si dicha colección llega de otro sitio y no es generada por la logica del método en cuestión).

Mario de Frutos

unread,
Aug 2, 2011, 4:56:48 AM8/2/11
to agile...@googlegroups.com
El martes 2 de agosto de 2011 10:48:22 UTC+2, Enrique Comba Riepenhausen escribió:

On Aug 2, 2011, at 10:21 AM, Alfredo Casado wrote:

De hecho si tu clase en cuestión depende de un motor de expresiones regulares (como en el caso de Java) seria mas limpio extraer la funcionalidad de esa expresión a su propia clase y testarla por separado.

Supongamos que hago eso (que me parece perfecto), entonces tengo una clase donde su única responsabilidad es encapsular el motor de ER y ofrecer un interfaz que me guste más o encaje más con mi negocio al resto de mis clases, por ejemplo supongamos que tengo una clase para "sanear" cadenas eliminando ciertos caracteres especiales:

public class Saneador {

   public String limpiaYDaEsplendor(final String cadenaSucia) {
       
        return  motorDeJavaDeER.aplicarER("una ER que sirva para quitar caracteres especiales");
   }

}

Esta clase no tiene ninguna responsabilidad más que sanear una cadena, incluso podría hacerlo sin usar ER. LLegados a este punto ¿tiene realmente interés mockear el motorDeJavaDeER?.

Si

No quiero esperar a un test funcional para saber que escribo bien la expresión regular y que he llamado en el orden correcto a los métodos/objetos que tengo que usar el motor de ER, como soy muy olvidadizo nunca me acuerdo de como se hacen estas cosas y hacer un test con mocks primero que se limite a comprobar que llamo al motor con la ER que yo creo que es la correcta no me esta aportando en realidad gran cosa.

De hecho tendrías tests unitarios para tu Saneador que asegurarían que la clase Saneador funciona como es debido.

En los tests funcionales no escribirías ningún double ya que estas testando el comportamiento de la aplicación en su totalidad (i.e. con todos los componentes que la componen).
 
¿Entonces esos test unitarios, Mockearian la funcionalidad del motor de ER de Java? 

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 5:03:43 AM8/2/11
to agile...@googlegroups.com
On Aug 2, 2011, at 10:56 AM, Mario de Frutos wrote:

El martes 2 de agosto de 2011 10:48:22 UTC+2, Enrique Comba Riepenhausen escribió:
En los tests funcionales no escribirías ningún double ya que estas testando el comportamiento de la aplicación en su totalidad (i.e. con todos los componentes que la componen).
 
¿Entonces esos test unitarios, Mockearian la funcionalidad del motor de ER de Java? 

No, en este caso , en el test de la clase Saneador estaria comprobando que mi expresion regular de comporta de manera correcta.

Alfredo Casado

unread,
Aug 2, 2011, 5:41:35 AM8/2/11
to agile...@googlegroups.com
A ver si te entiendo bien enrique, con la clase de antes

public class Saneador {

   public String limpiaYDaEsplendor(final String cadenaSucia) {
       
        return  motorDeJavaDeER.aplicarER("una ER que sirva para quitar caracteres especiales", cadenaSucia);
   }

}

Puedo hacer un test con mocks más o menos así:

        MotorDeJavaDeER motorER = mock(....)
        Saneador saneador = new Saneador(motorER); 
        saneador.limpiaYDaEsplendor("cadena sucia");

        verify(motorER).aplicarER("una ER que sirva....", "cadena sucia")

y luego podría hacer un test que compruebe si la clase tiene el comportamiento esperado, aunque para esto necesite instanciar un motor de ER real:

      Saneador saneador = new Saneador (new MotorDeERDeJava());   
     
      assertThat(saneador.limpiaYDaEsplendor("cadena sucia"), is("cadena limpia")); 

¿Tu cual de estos harías?, ¿los dos?, ¿el primero o el segundo?

Yo sólo haría el segundo, al primero no veo que me este aportando mucho, no me sirve para comprobar que la ER esta bien y además si en el futuro quiero cambiar esta ER por otra más optima pero que haga lo mismo el test me va a fallar. 


Leo Antoli

unread,
Aug 2, 2011, 5:49:38 AM8/2/11
to agile...@googlegroups.com
Enrique,
me surge la duda de si haces TDD haciendo pruebas unitarias probando solo la interacción con los colaboradores, si no puede pasar que acabe siendo una forma de hacer prácticamente lo mismo dos veces. Es decir, haces un test en el que quieres probar que tal clase llame a tales colaboradores de tal forma, falla el test, implementas la clase llamando a los colaboradores y el test pasa. 

¿ no sería más o menos hacer lo mismo de dos formas diferentes ? 

¿ que extra te aporta este test unitario, es solo para ayudarte en el diseño de la clase, o también te aporta algo a nivel de pruebas ?

Saludos,
Leo



2011/8/2 Enrique Comba Riepenhausen <eco...@gmail.com>

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 6:03:57 AM8/2/11
to agile...@googlegroups.com
On Aug 2, 2011, at 11:41 AM, Alfredo Casado wrote:

A ver si te entiendo bien enrique, con la clase de antes

public class Saneador {

   public String limpiaYDaEsplendor(final String cadenaSucia) {
       
        return  motorDeJavaDeER.aplicarER("una ER que sirva para quitar caracteres especiales", cadenaSucia);
   }

}

Puedo hacer un test con mocks más o menos así:

        MotorDeJavaDeER motorER = mock(....)
        Saneador saneador = new Saneador(motorER); 
        saneador.limpiaYDaEsplendor("cadena sucia");

        verify(motorER).aplicarER("una ER que sirva....", "cadena sucia")

y luego podría hacer un test que compruebe si la clase tiene el comportamiento esperado, aunque para esto necesite instanciar un motor de ER real:

      Saneador saneador = new Saneador (new MotorDeERDeJava());   
     
      assertThat(saneador.limpiaYDaEsplendor("cadena sucia"), is("cadena limpia")); 

¿Tu cual de estos harías?, ¿los dos?, ¿el primero o el segundo?

Yo sólo haría el segundo, al primero no veo que me este aportando mucho, no me sirve para comprobar que la ER esta bien y además si en el futuro quiero cambiar esta ER por otra más optima pero que haga lo mismo el test me va a fallar.

Probablemente algo mas parecido al primero.

En tu caso tendrías tests unitarios de MotorDeERDeJava (aunque el nombre me parece horrible) que ya aseguran que hace lo que hace. Si esto fuese así, acabaríamos con el test de Saneador de esta manera:

Imaginemos que la expresión regular que queremos aplicar quita palabrotas.

SwearWordRemover swearWordRemover = mock (SwearWordRemover.class);

Saneador saneador = new Saneador(swearWordRemover);
when(swearWordRemover.removeSwearwords(dirtyString)).thenReturn(cleanString);

saneador.cleanAndShine(dirtyString);

verify(swearWordRemover).removeSwearwords(dirtyString);

Con esto si la implementación de SwearWordRemover cambia en un futuro seguiremos con el test funcionando ya que lo que nos interesa aqui es que se llame al metodo en cuestión y no el resultado del mismo (el resultado ya lo testamos en la clase de test de SwearWordRemover).

Un saludo,

Enrique

Carlos Ble

unread,
Aug 2, 2011, 4:27:37 PM8/2/11
to agile-spain
Hola!
Aunque puede ser necesario en alguna ocasion hacer esto, (por ejemplo
con legacy), yo prefiero encapsular las llamadas a terceros en clases
mias, y estas son las que reemplazo con dobles en los tests.
Estoy seguro que tu tambien lo haces así pero quería expresarlo para
quienes no están habituados a los dobles de test.

Good night :-)
> >> > Para tener acceso a más opciones, visita el grupo enhttp://groups.google.com/group/agile-spain?hl=es.
>
> >> --
> >> Has recibido este mensaje porque estás suscrito al grupo "agile-spain" de Grupos de Google.
> >> Para publicar una entrada en este grupo, envía un correo electrónico a agile...@googlegroups.com.
> >> Para anular tu suscripción a este grupo, envía un correo electrónico a agile-spain...@googlegroups.com
> >> Para tener acceso a más opciones, visita el grupo enhttp://groups.google.com/group/agile-spain?hl=es.
>
> > --
> > Has recibido este mensaje porque estás suscrito al grupo "agile-spain" de Grupos de Google.
> > Para publicar una entrada en este grupo, envía un correo electrónico a agile...@googlegroups.com.
> > Para anular tu suscripción a este grupo, envía un correo electrónico a agile-spain...@googlegroups.com
> > Para tener acceso a más opciones, visita el grupo enhttp://groups.google.com/group/agile-spain?hl=es.

Enrique Comba Riepenhausen

unread,
Aug 2, 2011, 6:49:28 PM8/2/11
to agile...@googlegroups.com

On 02/08/2011, at 22:27, Carlos Ble <ble.j...@gmail.com> wrote:

> Hola!
> Aunque puede ser necesario en alguna ocasion hacer esto, (por ejemplo
> con legacy), yo prefiero encapsular las llamadas a terceros en clases
> mias, y estas son las que reemplazo con dobles en los tests.
> Estoy seguro que tu tambien lo haces así pero quería expresarlo para
> quienes no están habituados a los dobles de test.

Correcto :)
>

Enrique Comba Riepenhausen
.:: Software Craftsman ::.

http://ecomba.org
twitter: @ecomba
Skype: ecomba

--typos by apple

Reply all
Reply to author
Forward
0 new messages