Rompiendo los limites: Mocking en las Pruebas Unitarias .Net

MockingRompiendo los limites: Mocking en las Pruebas Unitarias .Net

Hoy por fin os traigo la unión entre las Pruebas Unitarias y la Inyección de Dependencias, el “Mocking“. ¿Que es el “Mocking” te preguntarás?, pues es la técnica utilizada para simular objetos en memoria con la finalidad de poder ejecutar pruebas unitarias.

Esto, es especialmente útil cuando utilizamos recursos externos como bases de datos o servicios de mensajería, o cualquier cosa en general que no queramos o no podemos ejecutar durante las pruebas unitarias.

Sin mas preámbulos, ¡vamos con ello! En primer lugar, he reutilizado el proyecto Entity Framework Core “Code First” para partir de tener el contexto de datos creado. Ademas, he añadido una clase “GeneradorInformes” (la cual cumple el patrón de Inyección de Dependencias en el constructor) y una clase “EmailSender” que implementa la interfaz “IEmailSender”:

Proyecto

El resumen del funcionamiento básico, es que GeneradorInformes recibe las dependencias del contexto de datos y el servicio de correo, y al llamar al método “GenerarInforme(string,string)” se obtiene el informe del cursos y alumnos del profesor indicado, y se envía al correo indicado. En caso de que el informe se genere correctamente y se envíe, retornamos un true, en caso contrario un false.

Pruebas Unitarias y Mocking

Generaremos un proyecto de pruebas unitarias en nuestra solución y añadimos a nuestro proyecto de pruebas el siguiente paquete:

Moq.Net

O por consola:

PM-> Install-Package Moq -ProjectName “NombreProyectoPruebas”

Este paquete esta alineado con .NetStandard, en concreto .NetStandard 1.3, por lo que se puede utilizar indistintamente en .Net Framework o en .Net Core. Una vez que lo tenemos todo listo, vamos a crear nuestra prueba unitaria para GeneradorInformes.

Analicemos la clase de pruebas. En primer lugar, tenemos 2 objetos de tipo “Mock<T>” , declarados a nivel de clase, esto es debido a que vamos a utilizarlos en las 2 pruebas, y así nos ahorramos tener que construirlos 2 veces, aligerando así la carga.

Mock<IEmailSender>

Lo siguiente que tenemos, es el constructor. En él, se inicializan los objetos Mock, vamos de uno en uno:

Mediante el método “Setup”, le estamos indicando el comportamiento que debe tener cuando llamemos el método Enviar(string,string) de la interfaz. Cabe destacar que “It.IsAny<string>()” esta indicando que este Mock se aplicara ante cualquier entrada de tipo string, pero podríamos indicarle un string concreto, por ejemplo:

Con este segundo código, solo aplicaría el Mock si el primer string es “FixedBuffer”, pudiendo definir así diferentes comportamientos ante diferentes entradas ya que podemos llamar tantas veces al método Setup como queramos.

Mock<PostMockingDbContext>

En este caso, no vamos a generar generar un comportamiento en concreto, sino que vamos a generar un contexto de datos falso. Lo primero para eso, es crear una colección de datos:

Como se puede ver, simplemente estamos creando la colección que luego convertiremos en el contexto de datos. Una vez que tenemos los datos, vamos a crear el Mocking del DbSet, que como se puede ver, simplemente consiste en relacionar la colección que acabamos de crear con el objeto Mock<DbSet<Profesor>>.

En el caso de necesitar mockear más tablas, solo tendríamos que repetir el proceso con todas las tablas que nos interese. Una vez que hemos acabado de generar todos los datos que tendrá nuestro contexto, asignamos los DbSet mokeados, vamos a crear por fin nuestro “Mock<PostMockingDbContext>”:

Esto lo conseguimos diciéndole en el Setup que ante un acceso a la tabla “Profesores”, devuelva el objeto mock que acabamos de crear.

Una vez que tenemos creados nuestros dos objetos “Mock<T>” para las pruebas, veamos las pruebas:

Como se puede ver, el funcionamiento es exactamente igual que sería en nuestro proyecto en producción, pero en vez de pasarle el PostMockingDbContext y EmailSender, las cuales pueden no estar disponibles para las pruebas, le pasamos sus respectivos Mock, de modo que siempre podemos prever el comportamiento, pudiendo hacer pruebas que sean fiables, sin necesidad de que se tenga acceso a recursos externos. Esto es especialmente útil si se emplean herramientas de CI como Travis o AppVeyor, ya que no van a tener acceso a esos recursos. De hecho, os dejo el enlace a una colaboración que hice hace unos meses hablando sobre AppVeyor y la integración continua.

Ademas, como dato adicional, podemos ver la salida de consola del test unitario, donde ademas de saber que se ha ejecutado correctamente, podríamos ver el reporte:

report

Como habitualmente, dejo el enlace de GitHub para descargar el proyecto y poder probarlo, en este caso, desarrollado en .Net Core. Para ampliar información, dejo también la documentación de Moq.Net.

¡Reconocimiento MVP Award 2018!

      6 comentarios en ¡Reconocimiento MVP Award 2018!

MVP Award

Hoy por la tarde he recibido un correo de Microsoft que decía:

mvp

Estoy muy ilusionado de recibir este reconocimiento a la labor de este tiempo en MSDN y estas ultimas semanas con el blog, solo espero poder seguir aprendiendo y estar a la altura de este galardón.

Es todo un honor para mi poder entrar a formar parte de este grupo de grandes profesionales, entre los que están muchas personas que admiro por su gran labor, como el gran Leandro Tuttini, el señor Williams Morales o don José M. Aguilar, cuyo blog Variable not found (de obligada lectura, mis dieces) me incito a abrir el mio.

Muchas gracias al programa MVP de Microsoft por darme este premio.

Muchas gracias a los compañeros que me aguantáis día a día me aguantáis hablando sobre proyectos interesantes, algunos incluso sin poder huir durante la ida y vuelta al trabajo (Eso lo sabe bien Rubén de MascandoBits, la otra persona que incito a abrir un blog, incluso haciendo algunas colaboraciones en el suyo, mis dieces también).

Pero sobre todo, millones de gracias a mi familia que me ha apoyado, y en especial a mi novia que es la que mas tiene que aguantar los días pegado a la pantalla del ordenador y la que más me apoya, sin ella, nada de esto sería posible.

 

Venciendo el miedo a las pruebas unitarias en .Net

Test Unitario

Otro día más por aquí, y hoy vengo a hablaros de las “Pruebas Unitarias”. Las pruebas unitarias son herramientas de testing para asegurar que nuestro código no cambia su funcionalidad pese a que hagamos cambios en él. Es decir, imaginemos que tenemos una librería matemática con unas operaciones simples:

Como se puede ver, es una clase muy simple de ver, entender, y probar su funcionamiento pero… ¿Que pasaría si una de estas operaciones básicas fallase por un cambio no comprobado? Pues probablemente, no pensaríamos que algo tan simple puede estar fallando… y eso que podemos haberlo cambiado incluso sin darnos cuenta…

Para evitar ese tipo de fallos, existen este tipo de herramientas, cuya finalidad es que, ante unos datos de entrada conocidos, si todo va bien, tenemos que tener unos datos de salida que podemos predecir y comprobar.

Pruebas Unitarias en Net Framework

Como habitualmente, crearemos un proyecto de consola:

ProyectoConsolaNetClasico

Y en el introduciremos la clase ProcesadorMatematico de la que acabamos de hablar. Una vez hecho eso, vamos a crear un nuevo proyecto en la solución, pero esta vez de pruebas unitarias:

PruebasUnitariasNetClasico

Con esto, veremos que se nos crea un proyecto nuevo dentro de la solución, con una clase por defecto:

En ella vemos 2 decoradores, [TestClass] , el cual indica que esa clase va a ejecutar pruebas unitarias, y [TestMethod], el cual indica que ese método es una prueba unitaria. Da igual el nombre de la clase y de los métodos, siempre que tengan los atributos correspondientes.

Como en cualquier otro proyecto, tenemos que referenciar los proyectos que queremos usar:

referencia

Una vez hecho esto, podremos acceder a las clases añadiendo el using correspondiente. Vamos a crear un test para algunas operaciones, así que nos quedara algo como esto:

Para poder comprobar los resultados visualmente, la opción más cómoda es sacar la ventana de pruebas, para ello, vamos al menú Prueba->Ventanas->Explorador de pruebas unitarias. Esto nos añade una ventana al cuadro de herramientas:

VentanaPruebas

En ella, pulsaremos ejecutar todo, y veremos que nos muestra los resultados de las pruebas:

PruebasOK

Pero… que pasaría si por algún problema no pasa la prueba? Vamos a probarlo cambiando el método “Sumar” por :

Si volvemos a lanzar la prueba:

PruebaNOK

Efectivamente, las pruebas unitarias detectan rápidamente que algo no va bien…

Puedes descargar el código de ejemplo aquí.

Pruebas Unitarias en Net Core

Vamos a crear otro proyecto de consola, esta vez de NetCore:

consola .net core

Y en el vamos a añadir nuestra clase igual que antes. Una vez hecho, vamos a crear un proyecto de pruebas:

PruebasUnitariasNetCore

Y generamos una clase de pruebas como la anterior. Ejecutamos las pruebas exactamente igual que antes, y como podemos ver, los resultados son los mismos. Dejo un enlace al código fuente del proyecto para poder descargarlo.

Como se puede ver, las pruebas unitarias nos aseguran que nuestros cambios no comprometen el funcionamiento de nuestros programas, dándonos ese extra de tranquilidad al poder añadir pruebas para prácticamente cualquier cosa que se nos ocurra.

En futuros post, ampliaremos este tema tan versátil utilizando “Mocking” para simular las bases de datos y escribiendo clases “fake” para probar clases diseñadas según el patrón de inyección de dependencias

Inyección de Dependencias en .Net Framework

Inyeccion de dependencias

Un mes ya… y hoy vengo a hablaros de la “Inyección de Dependencias” (DI). La inyección de dependencias consiste de manera resumida en evitar el acoplamiento entre clases utilizando interfaces. Gracias esto, conseguimos que cada clase tenga una función única, facilitando así el mantenimiento y el soporte de nuestro código.

Esto que puede parecer un poco lioso a simple vista, y puede parecer mucho trabajo, se puede conseguir fácilmente cambiando levemente nuestro patrón de diseño. Vamos a imaginar que tenemos una clase que lee unos datos desde una base de datos con Entity Framework (“Database First” o “Code First“), y los envía por email:

En primer lugar, vamos a analizar los posibles problemas de esta clase:

  1. Baja mantenibilidad por el acoplamiento en entre clases: Es la propia clase la que instancia las que va necesitando, provocando que cualquier cambio en las clases “auxiliares” pueda cambiar el comportamiento.
  2. Dificultad para realizar pruebas unitarias: En el caso en el que queramos realizar pruebas unitarias, es requisito que todos los servicios estén activos. Desde el punto de vista de las pruebas, esto es nefasto, podemos no tener acceso al servidor de correo, o a la base de datos… Con este patrón, es muy difícil testear nuestra clase.

Inyección de Dependencias

Vamos a ver que pasa si refactorizamos la clase para inyectar las dependencias, de manera que no tengamos dependencias:

Hemos conseguido una mayor mantenibilidad al abstraer totalmente a la clase “GeneradorInforme” de las labores propias de envío de correo y de obtención de datos. Y ahora es cuando me dices, “Pero no hace falta utilizar inyección de dependencias para conseguir lo que has conseguido…”. Efectivamente, para simplemente desacoplar las clases, no sería necesario. Podríamos haberle pasado al método una instancia de EmailSender en vez de su interfaz pero… Si queremos hacer pruebas unitarias, eso no es suficiente. Seguiríamos con el problema de que si el servidor de correo esta caído, nuestra prueba fallaría. Ahí radica la potencia de trabajar inyectando dependencias. En nuestro proyecto de pruebas unitarias, simplemente tendríamos que añadir una nueva clase que implemente “IEmailSender” y que no se conecte a ningún servidor, o que simule la conexión.

En el caso del ejemplo, hemos inyectado las dependencias mediante un parámetro, pero esta solo es una de las maneras. Podemos inyectar dependencias de varias maneras:

  1. Inyección de dependencias en parámetros de constructor.
  2. Inyección de propiedades.
  3. Inyección de dependencias en parámetros de métodos.

Vamos a ver más detalladamente cada uno.

Inyección de dependencias en parámetros de constructor

 Inyección de propiedades

En este caso, hay que tener en cuenta que la dependencia no estará disponible durante el constructor, por si la necesitásemos.

Inyección de dependencias en parámetros de métodos

Es el caso que hemos visto en el primer ejemplo.

Contenedor IOC

La utilización de contenedores IOC (Inversion Of Control) nos abstraen de la necesidad de generar las clases cada vez. Simplemente es configurar un contenedor el cual nos sirva las dependencias que necesitamos en cada momento. Esto facilita mucho la labor de trabajo al no tener que gestionar nosotros mismos las clases. Existen bastantes sistemas IOC para .NET, pero en este caso, vamos a utilizar “Microsoft.Extensions.DependencyInjection”.

Para eso, tenemos que añadir el paquete desde NuGet:

DI

O vía consola:

PM->Install-Package Microsoft.Extensions.DependencyInjection -Version 2.1.1

Ahora vamos a registrar los servicios (Asumo que tenemos un DbContext creado en base a los post de Entity Framework  Core), pero para ello, primero tenemos que crear el interfaz IGeneradorInformes y hacer que Generador de informes la implemente:

Una vez que lo tengamos, empezamos a registrar los servicios:

Después, simplemente necesitamos llamar a su metodo “GetService<T>()” para obtener una instancia de la clase concreta con todas sus dependencias inyectadas:

Este sistema funciona muy bien en MVC 5 y MVC Core, ya que esta construido totalmente sobre el sistema de inyección de dependencias, pero es cierto que en aplicaciones que no sean MVC, hay que trabajarselo un poco. Digo esto porque necesitamos mantener activa una referencia a “services” para poder pedirle las clases. Esto lo podemos resolver bastante fácilmente con un tipo estático que almacene nuestra referencia:

Veamos como usarlo en nuestro código:

Con esto, registraremos todas las dependencias al inicio de nuestro programa, y llamaremos a Injector.GetService<T>() cuando necesitemos utilizar una dependencia.

A simple vista, parece que es mucho trabajo y poca recompensa, pero en las siguientes entradas veremos las ventajas que aporta trabajar así cuando hablemos de las pruebas unitarias y del “Moking”.

Puedes descargar el código de ejemplo desde este enlace.

Haciendo fácil el acceso a datos con Entity Framework Core (Parte 2)

Entity Framework Core

Venimos con la segunda parte de “Haciendo fácil el acceso a datos con Entity Framework Core“. Esta vez, vamos a hacer el mismo ejemplo, pero con la opción “Code First”. Utilizando esta opción, vamos a generar nuestra base de datos mediante clases que relacionaremos entre ellas, así veremos las dos caras de la moneda.

Modelo

Tengamos el objetivo claro, mediante la opción “Code First” vamos a buscar conseguir un modelo como este:
Modelo DB

En el tenemos 2 relaciones 1 a muchos:

  1. Un profesor podrá impartir varios cursos.
  2. Cada curso puede tener varios alumnos.

Creando la solución en Visual Studio

En primer lugar, vamos a crear el proyecto, solo que esta vez, será un proyecto de consola Net Core:

consola .net core

Paquetes

Como la vez anterior, instalamos los paquetes de Entity Framework Core vía NuGet:

efctools

En caso de querer hacerlo vía consola:

PM->Install-Package Microsoft.EntityFrameworkCore -Version 2.1.3
PM->Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.1.3

Y lo mismo para el proveedor de MySql

pomelo

O como siempre, por consola:

PM->Install-Package Pomelo.EntityFrameworkCore.MySql -Version 2.1.2

Creando la solución en DotNet CLI

Una de las ventajas de Net Core es que nos permite ejecutar sus acciones desde línea de comandos, con eso, conseguimos toda la funcionalidad en plataformas como Linux. En este caso, utilizaremos la Powershell. Para crear un proyecto, crearemos una carpeta y navegaremos a ella con:

– mkdir PostEntityCore
– cd PostEntityCore

Una vez dentro de la carpeta, crearemos el proyecto y añadiremos los paquetes con:

– dotnet new console
– dotnet add package Microsoft.EntityFrameworkCore -v 2.1.3
– dotnet add package Microsoft.EntityFrameworkCore.Tools -v 2.1.3
– dotnet add package Pomelo.EntityFrameworkCore.MySql -v 2.1.2

Generando el DbContext

En este caso, el modelo lo vamos a generar mediante clases en nuestro proyecto, a fin de organizar el proyecto, añadiremos una carpeta “Data” a la solución, donde añadiremos las siguientes clases:

Entity Framework Core

Vamos a desgranar las clases:

Entity Framework Core “Code First” en Visual Studio

Una vez tenemos el contexto creado en nuestro proyecto, iremos a la “Consola del Administrador de paquetes”, y ahí dispondremos de estos comandos:

  1. add-migration {nombre} -Context {contexto}
  2. remove-migration
  3. update-database {nombre} -Context {contexto}
  4. drop-database -Context {contexto}

Vamos a explicar los comandos:

add-migration: Con este comando, generaremos la migración que lanzaremos a la base de datos. Este comando tiene 2 parámetros:

  1. {nombre}: Con este parámetro indicaremos el nombre que queremos indicarle a la migración, ademas, es obligatorio.
  2. -Context {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

remove-migration: Con este comando, eliminaremos la ultima migración que hemos generado. Se puede utilizar varias veces consecutivamente para ir eliminando migraciones desde la última a la primera.

update-database: Con este comando, enviaremos a la base de datos los cambios de la migración, haciéndola efectiva:

  1. {nombre}: Con este parámetro indicaremos el nombre de la migración que queremos aplicar.
  2. -Context {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

drop-database: Con este comando, eliminaremos la base de datos. Este comando tiene 1 parámetro:

  1. -Context {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

Una vez que conocemos los comandos, vamos a ponernos en faena… Para empezar, utilizamos el comando:

add-migration init -Context PostDbContext

Esto genera una carpeta “Migrations” donde va a ir guardando cada una de las migraciones. Conviene no borrar el contenido, ya que almacena las “versiones” del contexto de datos, de modo que podemos revertir los cambios en la base de datos. Ademas, el hecho de almacenar estas migraciones, permite al sistema aplicar cambios de manera incremental en las próximas migraciones, y es requisito para poder aplicar cambios a la base de datos sin que se produzcan errores por tablas ya existentes.

Con eso, ejecutamos:

update-database -Context PostDbContext

Entity Framework Core “Code First” en DotNet CLI

Igualmente, podemos hacer toda la labor desde el cli de dotnet con los comandos equivalentes de “dotnet ef”:

  1. migrations add {nombre} -c {contexto}
  2. migrations remove
  3. database update {nombre} -c {contexto}
  4. database  drop -c {contexto}

Vamos a explicar los comandos:

migrations add: Con este comando, generaremos la migración que lanzaremos a la base de datos. Este comando tiene 2 parámetros:

  1. {nombre}: Con este parámetro indicaremos el nombre que queremos indicarle a la migración, ademas, es obligatorio.
  2. -c {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

migrations remove: Con este comando, eliminaremos la ultima migración que hemos generado. Se puede utilizar varias veces consecutivamente para ir eliminando migraciones desde la última a la primera.

database update: Con este comando, enviaremos a la base de datos los cambios de la migración, haciéndola efectiva:

  1. {nombre}: Con este parámetro indicaremos el nombre de la migración que queremos aplicar.
  2. -c {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

database drop: Con este comando, eliminaremos la base de datos. Este comando tiene 1 parámetro:

  1. -c {contexto}: En caso de tener más de un contexto de datos en nuestro programa, indicaremos cual de los contextos es mediante este parámetro. Si solo tenemos un contexto de datos, no es obligatorio usarlo.

Una vez que conocemos los comandos del CLI, vamos a ello

dotnet ef migrations add init -c PostDbContext

En este caso, debemos tener las mismas cosas en consideración que si lo hiciésemos desde Visual Studio.

Con eso, ejecutamos:

dotnet ef database update -c PostDbContext

Resultado

Una vez hecho esto de cualquiera de las 2 maneras, desde el gestor de nuestra base de datos, veremos que se ha creado la base de datos, y si aplicamos la ingeniería inversa para reconstruir el modelo (desde el MySql Workbench), veremos algo así:Entity Framework Core:

Vemos que hemos conseguido generar el modelo que queríamos, pero tenemos una tabla más, “__efmigrationshistory”, en esta tabla es donde Entity Framework Core registra las versiones del contexto que están aplicadas en la base de datos.

Ejemplo

En mi perfil de GitHub he dejado un ejemplo del proyecto, el cual una vez aplicadas las migraciones sobre la base de datos, podemos ver que funciona correctamente ante la misma lógica de programa de la primera parte:

Nos devolverá:

El alumno Juan recibe el curso de Matematicas,impartido por Pedro
El alumno Jorge recibe el curso de Matematicas,impartido por Pedro
El alumno Sandra recibe el curso de Lenguaje,impartido por Pedro
El alumno Andrea recibe el curso de Lenguaje,impartido por Pedro

En caso de no tener Visual Studio, lanzaremos el proyecto desde el CLI de dotnet con :

dotnet run –proyect PostCore

Aviso a navegantes

En caso de que no queramos almacenar las migraciones, se pueden borrar del proyecto eliminándolas como archivo, o simplemente con:

PM -> remove-migration
CLI -> dotnet ef migrations remove

Pero cada vez que queramos crear una nueva migración y aplicarla, no existirá la migración previa, de manera que tendremos que hacer un drop a la base de datos mediante

PM-> drop-database -Context PostDbContext
CLI-> dotnet ef database dtop -c PostDbContext

asumiendo con ello la consiguiente perdida de datos. En caso contrario, el update lanzará un error indicando que las tablas ya existen en la base de datos.

En entornos de desarrollo, no es necesario revisar la migración ya que presumiblemente no nos importa la posible perdida de datos, pero si vamos a aplicar migraciones en entornos de producción, conviene que revisemos los ficheros generados en la migración, donde veremos que se definen 2 métodos:

Estos dos métodos serán ejecutados durante las actualizaciones de la base de datos (“Up” al aplicar un migración y “Down” al quitarla) y conviene que estemos seguros de que si por ejemplo queremos cambiar como almacenamos los datos de un nombre, unificando dos columnas, hacemos que se genere una nueva columna, se migren los datos de las previas a la nueva, y entonces se borren la previas, de modo que no tengamos una perdida de datos. En cualquier caso, siempre que la migración tenga posibilidades de que se produzca una perdida de información, Entity Framework Core nos lo notificara con el mensaje:

Entity Framework Core

En este enlace, dejo un ejemplo de la documentación oficial detallando más sobre ese tema.

Haciendo fácil el acceso a datos con Entity Framework Core

Imagen EFCore

Segunda entrada en el blog y vengo a hablaros de otra situación que se dio en mi oficina…
Otro compañero acaba de meterse en un proyecto de uso intensivo de bases de datos en el que requiere de una herramienta que le solucione la papeleta.

En mi día a día, he trabajado bastante con Entity Framework 6, el “clásico”, pero hace algún tiempo encontré Entity Framework Core . Entity Framework Core partió con un set de herramientas bastante limitado, no habiendo comparación posible con su “hermano mayor” Entity Framework 6. Pese a todo, Entity Framework Core fue diseñado con la filosofía de la era “cloud”, y estaba super optimizado para las cosas que hacía. Todo esto ha cambiado con la versión 2.0, (os dejo un enlace con la comparación y set de utilidades).

En el momento actual, tenemos entre manos una herramienta que si bien no es tan madura como Entity Framework 6, si tiene un madurez a tener en cuenta. Un punto a favor muy fuerte que tiene, es su posibilidad de ejecución multiplataforma, lo cual, nos permite usarlo con .Net Framweork o con .Net Core (¡y eso a mi me encanta!).

Una vez dicho esto, vamos a meternos en faena… ¿Como resolvimos esto? Como es de suponer, ¡¡¡con Entity Framework Core!!!. En este caso, como se dispone del modelo de la base de datos, utilizamos la opción “Database First”. Aunque también existe la opción “Code First”, para que la base de datos se genere desde el código, y hablaremos de ella en otro post…

Modelo

Para este caso, he creado un modelo como este:
Modelo DB

En el tenemos 2 relaciones 1 a muchos:

  1. Un profesor podrá impartir varios cursos.
  2. Cada curso puede tener varios alumnos.

En este caso, utilizaré para el ejemplo una base de datos MySql, al ser una base de datos gratuita.

Teniendo claro el modelo, vamos al lío!

Creando la solución

Lo primero, sera crear un proyecto de consola en c# y .Net Framework (o .Net Core, lo que se prefiera):

 

consola .net full

Paquetes

Con el proyecto creado, vamos a descargar los paquetes de Entity Framework Core vía NuGet:

efctools

En caso de querer hacerlo vía consola:

PM->Install-Package Microsoft.EntityFrameworkCore -Version 2.1.3
PM->Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.1.3

Solo falta descargar el proveedor de datos,en este caso MySql, y para eso, vamos a utilizar una implementación que va muy bien con Entity Framework Core:

pomelo

O como siempre, por consola:

PM->Install-Package Pomelo.EntityFrameworkCore.MySql -Version 2.1.2

Generando el DbContext

Una vez que tenemos todo instalado, vamos a ejecutar la generación del contexto. Para eso, usaremos el comando “scaffold” en la Consola de Administrador de Paquetes (No, Entity Framework Core no dispone de interfaz. Pero no requiere más que de unos pocos comandos, vamos, que no va a ser muy duro).

PM->scaffold-dbcontext “Server=localhost;Database=postefcore;Uid=root;Pwd=root;” Pomelo.EntityFrameworkCore.Mysql -outputdir Models -context PostDbContext

Analicemos los argumentos:

  1. -dbcontext
  2. -outputdir
  3. -context

En “dbcontext” le estamos pasando el contexto que queremos utilizar. Utilizaremos una cadena de conexión y un proveedor Entity Framework Core para eso. En este caso Pomelo.EntityFrameworkCore.Mysql, si utilizáramos otro, tendríamos que indicarlo aquí.

En “outputdir” le indicamos la ruta en nuestro proyecto donde queremos que cree las clases necesarias para funcionar.

En “context” le indicamos el nombre que le queremos dar a nuestro contexto de datos.

Una vez termine la ejecución, veremos algo como esto en nuestro proyecto:

Contexto

En caso de que lo que queramos sea actualizar el modelo porque hemos hecho cambios en la db, lo haríamos con el siguiente comando:

PM->scaffold-dbcontext “Server=localhost;Database=postefcore;Uid=root;Pwd=root;” Pomelo.EntityFrameworkCore.Mysql -outputdir Models -context PostDbContext -force

En este caso, hemos añadido el argumento – force para que sobre escriba lo que hay.

Puedes leer más sobre los argumentos aquí.

Insertando datos

Con esto que hemos hecho, ya podemos acceder a la base de datos mediante el ORM, y operarla como necesitemos, por ejemplo, vamos a añadir 1 profesor, 2 cursos y 4 alumnos. Para ello, insertamos el siguiente código en nuestra clase program:

Pese a que las tablas requieren de IDs de las relaciones, y que la consulta no se ejecuta hasta llamar a SaveChanges(), Entity Framework Core es capaz de almacenar las relaciones y asignar los IDs correspondientes. Así evitamos tener que hacer una consulta para obtener el ID del profesor, antes de de añadírselo a un curso, o el id de un curso antes de añadírselo a un alumno. Esto es una gran ventaja, ya que evita la necesidad de una función, o de dos consultas a la base de datos. Por otro lado, cuando ejecutamos la llamada a SaveChanges(), Entity Framework Core rellena los datos de ids con los valores que se han asignado en la base de datos.

Leyendo datos

Ahora, vamos a leer datos aprovechando la navegación de propiedades. Con ella, vamos a obtener un profesor. Con el profesor,obtendremos todos sus alumnos sin necesidad de ejecutar varias consultas o un largo “inner join”. Para eso, insertamos el siguiente código:

(Para que podamos utilizar .Include, hay que añadir el using correspondiente)

Obteniendo por consola algo así:

El alumno Juan recibe el curso de Matematicas,impartido por Pedro
El alumno Jorge recibe el curso de Matematicas,impartido por Pedro
El alumno Sandra recibe el curso de Lenguaje,impartido por Pedro
El alumno Andrea recibe el curso de Lenguaje,impartido por Pedro

 

Lo cual vemos que coincide con los datos que hemos introducido, aportándonos así este ORM un nivel de abstracción que nos puede facilitar mucho la vida. Por no hablar de la posibilidad de realizar todo esto de manera asíncrona. Todo ello de manera transparente a nosotros, y sin ninguno esfuerzo adicional.

Cabe destacar, que aunque no lo he indicado expresamente, Entity Framework Core nos permite trabajar con las tablas de la base de datos mediante LinQ. De este modo,podemos trabajar con la base de datos sin necesidad de utilizar sentencias SQL, con una herramienta fuertemente tipada.

En el próximo post, hablaremos de la opción “Code First”, y ahondaremos en las bondades que nos aporta utilizar un Entity Framework Core.

Generación de ficheros “Excel” (xlsx) con ClosedXML

closedxml

Después de llevar tiempo pensando en empezar a crear un blog, la semana pasada un compañero me pidió ayuda en un proyecto en el que necesitaban generar un excel en un servidor, el cual se enviaría al cliente, pero el servidor podía o no tener excel…

    -Para para!! ¿y tu quien eres?
-Tienes razón, no me he presentado…

Antes de nada, me voy a presentar, yo soy Jorge, un apasionado de las tecnologías de Microsoft, en especial .Net y Net Core. Trabajo como ingeniero de software en una empresa especializada en soluciones industriales, y es este bagaje el que me lleva querer compartir esas cosillas que he ido aprendiendo.

Bueno, volviendo a la materia… Un compañero me pidió ayuda para generar un fichero “excel” sin necesidad de tener MS Excel, esto es algo que parece poco coherente, pero son muchas las situaciones en las que se necesita generar un documento de acceso público para programas que no necesariamente tenemos en nuestro servidor, ya sea por incompatibilidad o por ser propietarios. En este caso concreto, existe un SDK para poder hacer este trabajo, OpenXML. El principal problema de este SDK, es su pronunciada curva de aprendizaje, que hace que no sea rentable utilizarlo para usos puntuales…

Y ahí es donde entran implementaciones más ligeras como SpreadSheetLight o ClosedXML, siendo este ultimo del que vamos a utilizar hoy. Pero basta ya de hablar, y vamos a la carga!!

En primer lugar, crearemos un proyecto de consola de .Net Framweork:

Imagen planitllas

Lo siguiente que tenemos que hacer es añadir el paguete ClosedXML a traves de nuget. Esto se puede hacer a través de la “Consola de Administrador de Paquetes” con el comando:

“Install-Package ClosedXML -Version 0.93.1”

Otra opción, es utilizar el administrador que integra VS:

Teniendo ya instalado el paquete, en el propio program.cs, añadiremos el código básico del ejemplo de GitHub:

Esto, generará un excel llamado “HelloWorld” junto al ejecutable de la aplicación, pero obviamente, esto es un ejemplo básico en el que se ven las bondades que tiene… Es posible cargar archivos .xlsx que ya existan, pasando la ruta en el constructor y así editarlo, por ejemplo,vamos a modificar el caso anterior para cargar un excel y añadir otra pestaña llamada FixedBuffer, que contenga el lo mismo pero en mayúsculas:

Como se ve en el ejemplo anterior, podemos utilizar LinQ para movernos entre las hojas y celdas, lo cual nos facilita mucho el trabajo de acceder a zonas concretas de nuestro documento.

En futuros post, ampliaré la información sobre ClosedXML para dar estilo a celdas, generar tablas y demás.

Solo una cosa más… En este ejemplo, hemos utilizado .Net Framework, pero si echamos un vistazo rápido al repositorio de GitHub o a NuGet…

Sorpresa!!! Es compatible con .Net Standard!!!! 

¿Que quiere decir esto? Pues que podríamos utilizarlo en nuestra aplicación Net Core y ASP Net Core, puediento generar documentos xlsx en nuestro código ejecutado en cualquier plataforma (No solo en Windows)

En el este enlace puedes descargar el código del proyecto