Enlaces e información

Comenta lo que creas oportuno.


Otros posts
Agilizando el desarrollo
Cosas con las que estoy…

Mockeando…

Escrito por Roberto M. Oliva en Febrero 7th, 2006

Tiene un nombre curioso y curioso es su funcionamiento y utilidad.
Muchas veces tenemos que testear una funcionalidad (Unit Testing) pero nos encontramos con dificultades al darnos cuenta de que la funcionalidad a testear depende mucho de factores externos: Bases de datos, ficheros, etc. Un principio básico del testeo dentro de la filosofía TDD (Test-Drivent Developement) es el del testeo aislado del resto: Si vamos a testear una funcionalidad, debemos asegurarnos de que nada interfiere en dicha funcionalidad y de que los resultados nos van a decir si hemos implementado bien o mal dicha funcionalidad y no otro artefacto relacionado o no con ella.

Para poder implementar esta premisa, existen los Mocks, cuya traducción es mofa, lo cual me hace pensar que puede ser una buena definición de los mismos: El código que vamos a testear utiliza un sistema externo pero en vez de que utilice dicho sistema externo le vamos a hacer utilizar una mofa del mismo, una mala copia.
Existe por la red una librería de clases que permite implementar mocks para testear: nMock dicha librería proporciona un mecanismo que genera objetos que cumplen cierto interfaz en tiempo de ejecución.
Supongamos que tenemos un interfaz como el siguiente:

1 Public Interface IProcesoExterno
 2   Function Llamada(ByVal strValor As String) As Integer
 3 End Interface

Y una clase que accede a un objeto que implementa este interface:

1  Public Class CClaseATestear
2     Public m_objProcExterno As IProcesoExterno
3
4     Public Sub New(ByVal objProcExterno As IProcesoExterno)
5         m_objProcExterno = objProcExterno
6     End Sub
7
8     Public Function FuncionATestear(ByVal strValor As String) As Integer
9         Return m_objProcExterno.Llamada(strValor)
10    End Function
11 End Class

Como se puede ver, la funcion a testear (en la linea 9 llamada, de manera original, FuncionATestear) llama a una de las funciones implementadas por el Interfaz. Queremos testear esa funcion, pero no queremos que se acceda al sistema externo que implemenat el interfaz. Para ello creamos un objeto mock que implementa la interfaz. Nuestra clase de testeo podría ser la siguiente:

1 <NUnit.Framework.TestFixture()> _
 2 Class CClaseTesteadora
 3
 4   Protected m_objMockControl As NMock.DynamicMock
 5
 6   <NUnit.Framework.SetUp()> _
 7   Public Sub SetUp()
 8       m_objMockControl = New NMock.DynamicMock(GetType(IProcesoExterno))
 9   End Sub
10
11    <NUnit.Framework.TearDown()> _
12    Public Sub TearDown()
13        m_objMockControl.Verify()
14    End Sub
15
16    <NUnit.Framework.Test()> _
17    Public Sub TestearFuncion()
18        Dim objClaseATestear As CClaseATestear
19        Dim iRet As Integer
20
21        ‘ Pasar el interfaz "mockeado" a la clase
22        objClaseATestear = New CClaseATestear(m_objMockControl.MockInstance)
23
24        ‘ Establecer el resultado de la funcion implementada por el interfaz
25        m_objMockControl.SetupResult("Llamada", 10, GetType(String))
26
27        ‘ Llamar a la funcion a testear
28        iRet = objClaseATestear.FuncionATestear("")
29
30        ‘ Comprobar que el resultado es correcto
31        NUnit.Framework.Assert.AreEqual(iRet, 10)
32    End Sub
33 End Class

Linea 8: Lo primero es, que en la inicialización de la clase de testeo, creamos un DynamicMock partiendo de la definición del interfaz.
Linea 22: Cuando creamos un objeto de la clase a testear, le pasamos una instancia del DynamicMock creado.
Linea 25: Definimos el comportamiento que tendrá la funcion de la interface. Estamos definiendo un comportamiento de una instancia de un objeto definido por un interfaz, que en realidad no existe. De alguna manera estamos engañando a la clase a testear. Lo bueno es que podemos definir que es lo que devuelve dicha funcion "engañosa".
Linea 31: Testeamos que la funcion devuelve lo que queremos. He simplificado mucho el codigo, para que sea muy entendible. Esta claro que no vamos a testear directamente lo que nos devuelva la funcion "mockeada", pero seguramente el resultado a testear depende mucho del comportamiento de la funcion "engañosa" utilizada.

Con todo esto podemos definir unas pruebas de testeo y controlar que, independientemente, de los agentes externos, nuestro código se comporta de la manera esperada. Que es el objetivo de las pruebas de testo unitarias.
Y esto solo es el principio….



Escriba un comentario

Dediquele un momento a comentar lo que piensa. Esta permitido usar HTML básico para formatear el escrito.

Comentarios de los lectores

Sea el primero en dejar un comentario.