EF 4.0: Testeando nuestros repositorios

De todos es sabido mi cariño por esta tecnología, reflejado sin duda en los numerosos artículos, entradas de blog y por su puesto el Libro ADO.NET EF publicado sobre la misma junto a mis colegas Octavio Hernandez y Eduardo Quintás. Por supuesto, ya desde hace bastante tiempo han salido betas y CTP sobre features que tendremos disponibles en Visual Studio 10 para lo que se ha llamado “Entity Framework 4.0”. A lo largo de futuros post y por supuesto de la segunda versión del libro intentaremos desgranar lo bueno de esta nueva versión y todos los ‘inconvenientes’ que hace más sencillos para la gente que se ha enfrentado a esta tecnología, sobre todo, para aquellos que la han implementado ( o intentado implementar ) en aplicaciones N-CAPAS.

Para esta primera entrada, de verdad :-), sobre EF 4.0, me gustaría centrarme en aspectos de test y test-doubles, es decir, ver como podemos con las nuevas API’s tratar  de testear nuestros repositorios de datos, y como hacer test-doubles de los mismos sin necesidad de acudir realmente a la base de datos.

El primer cambio importante que uno ve cuando de entrada crea un proyecto con EDM en Visual Studio 2010 y hecha un vistazo al código, independientemente de la plantilla de T4 seleccionada ( Clases prescriptivas, POCO o Selft Tracking Entities ) es que nuestros objetos de consulta que el contenedor pone a nuestra disposición ya no son directametne ObjectQuery<T> sinó ObjectSet<T>. Esta nueva clase, no es más que una herencia de la anterior, la cual, además de los tradicionales métodos de construcción de consultas agrega una serie de elementos que nos simplificarán un poco las cosas, como son por ejemplo los métodos AddObject, Attach y DeleteObject. Aunque a priori pueda parecer una nimiedad fíjese como en la versión actual de EF cuando queremos ‘Atachar’ una entidad dentro del contexto debemos realizar una especificación del EntitySet por medio de una cadena de caracteres, algo no muy elegante a la par de una fuente propensa de errores cuando el proyecto evoluciona, es decir, cuando los modelos tienen una frecuencia de cambio relativamente alta. Le recomiendo la lectura del post de Alex James dónde expone estos simples cambios y de paso como podríamos simularlos en .NET 3.5 SP1.

Además de los métodos comentados, la parte más interesante de esta nueva clase es que la misma se basa en la implementación de una interfaz, IObjectSet<T>, y por lo tanto es susceptible de ser simulada con cierta rapidez. Precisamente, es este punto, el que nos interesa dentro del trabajo a realizar para la creación de test-doubles con los contenedores de EF.

Supongamos que creamos un nuevo modelo de entidades que disponga de una entidad Person y que sobre el mismo decidimos crear nuestra implementación de contedor y entidades POCO.

Un ejemplo de nuestro contenedor podría ser algo similar a lo siguiente:

 

Como podrá observar sería muy sencillo readaptar nuestro contenedor para que el mismo se basara en una interfaz, que por ejemplo llamaremos IContainer y que tendría la siguiente firma.

 

 

Llegados a este punto, podríamos decir que ya tenemos las bases para poder hacer simulaciones de un contendor de trabajo. La pieza que tendríamos que simular sería una implementación ‘dummy’ de la interfaz IContainer, la cual puede ser fácilmente construída con Stub’s del que ya hemos visto cosillas en un video de Channel9@Spain o bien con cualquier otro framework de Mockering-Stubing como NMock, RhinoMock etc.. El problema principal que nos queda por resolver es la creación de nuestras simulaciones de IObjectSet, puesto que además de los elementos vistos esta interfaz es IQueryable<T> y por lo tanto debermos de dar una implementación a los métodos de la misma. Para resolver esta problemática utilizaremos el método extensor, AsQueryable(), que todos los elementos IEnumerable<T> ,como las listas genéricas, poseen y mediante el cual, podemos transformar directamente una colección de este tipo a Queryable<T>.

Con el fin de hacer esto de una forma más genérica y reutilizable para todos nuestros ObjectSet  partiremos de la siguiente clase.

 

 

Cómo se puede observar, esta nueva clase nos es más que la implementación de la interfaz IObjectSet a partir de una lista de elementos cualquiera y puede ser construída fácilmente por medio, por ejemplo, de un método extensor aplicado a las listas genéricas.

 

Llegados aquí, ya hemos construídas todas las bases de nuestro trabajo, vamos entonces, a realizar la tarea que nos ocupaba que consistía en realizar la implementación de Test de nuestros contenedores sin tener que acudir a la base de datos, para ello iremos utilizando todas las partes que hemos visto y creado anteriormente.

 

 

 

Como podemos observar en el código anterior, nuestro ejemplo de test crea una instancia de un contenedor creado por Stub’s, al cual le asignamos como ObjectSet de Person el creado a partir de una lista con nuestro nuevo método extensor, posteriormente, haremos las consultas, de igual forma que si estuvieramos trabajando contra ObjectSet de nuestros modelos de EF, es decir, como si estuvieramos trabajando con bases de datos.

 

Por supuesto, esto no es más que un ejemplo de trabajo sencillo, en futuras entradas iremos viendo como poner en práctica todo esto contra repositorios de nuestros contenedores de trabajo y como modificar nuestras plantillas de T4 para que podamos tener un alto grado de productividad, tanto para la realización de aplicaciones con EF 4.0 como para que las mismas sean fácilmente testeables.

 

Espero que os guste…

Un saludo

Unai Zorrilla Castro

4 comentarios sobre “EF 4.0: Testeando nuestros repositorios”

  1. Muy interesante Unai, pero tengo una pregunta.

    En este caso por lo q entiendo haces simplemente un stub del contendor, tiene sentido este tipo de test en una aplicación?

    Es q no lo veo demasiado claro, lo «normal» sería testear el repositorio contra una BBDD real o en memoria, o simular el repositorio para poder eliminar dependecias, pero el motivo de simular el contendor no lo veo.

    Un saludo!
    Carlos.

    PD: Para cuando el nuevo libro de EF? 🙂

  2. Parece que no me he podido explicar con demasiada claridad Carlos. Dentro del post no solamente se ve como eliminar la dependencia del contendor sino como además también de los objetos sobre los que puedes realizar la consulta. Con esto, de entrada ganas la posibilidad precisamente de poder pasar pruebas de tus repositorios sin necesidad de acceder a bases de datos ( que no quita que tb las tengas que pasar, pero las puedes omitir para pruebas de minuto a minuto de los desarrolladores). Si piensas, como comentas en repositorios, entendiendo estos por el patrón de Martin Fowler,http://martinfowler.com/eaaCatalog/repository.html, este ejemplo te permitirá quitar la dependencia con contendor real y poder trabajar con un objeto simulado y por lo tanto también poder testear los mismos como comentas contra objetos en memoria, de hay el método extensor para convertir una lista en un ObjectSet..

    Espero que este comentario aclare tus dudas y si no es así pues seguimos comentando 🙂

    P.D: El libro, pues para cuando salga la RTM de VS 2010 debería estar listo, pero nunca se sabe … 🙁

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *