Algo muy típico en todos los desarrollos es la necesidad de enviar correos electrónicos. En este post veremos cómo es posible probar de manera automatizada si nuestro método genera o no genera correos electrónicos.
En este caso vamos a simplificar y sólo vamos a probar un método que única y exclusivamente manda el correo. Nuestro método tendría el siguiente aspecto:
public static void SendMail(string from, string to, string subject, string body) { MailMessage msg = new MailMessage(from, to, subject, body); SmtpClient sm = new SmtpClient(); sm.Send(msg); }
Nuestro objetivo será asegurarnos que cuando llamamos a este método se genera un mensaje de correo. Vamos a suponer que todos los parámetros que se reciben son correctos, por lo que no se realiza ninguna validación de los mismos.
La primera aproximación sería algo así.
[TestMethod()] public void SendMailTest() { string from = "admin@admin.com"; string to = "target@sample.com"; string subject = "subject"; string body = "body"; Class1.SendMail(from, to, subject, body); }
El problema de esta aproximación, es que con esta prueba sólo podremos saber si la ejecución del método SendMail genera o no genera ninguna excepción, pero realmente no sabemos si se está enviando el mensaje.
Para poder comprobar realmente si el mensaje se envía necesitaríamos tener acceso al servidor SMTP o instalarlos uno en nuestro equipo para hacer las pruebas y poder acceder a él para comprobar si se ha enviado el mensaje…..la primera suele ser complicada por políticas de seguridad y la segunda me resulta un poco peñazo…
Como alternativa, el framework nos posibilita que podamos configurar el sistema de mensajería para que en lugar de usar un servidor SMTP para enviar los correos, simplemente éstos se dejen en disco, en un directorio. Para hacer pruebas unitarias esta característica resulta perfecta.
A través del fichero de configuración podremos indicar que los mensajes se dejen en disco:
<system.net> <mailSettings> <smtp deliveryMethod="SpecifiedPickupDirectory"> <specifiedPickupDirectory pickupDirectoryLocation="c:MailMessages" /> <network host="127.0.0.1" port="25"/> </smtp> </mailSettings> </system.net>
Ten en cuenta que esta configuración la tienes que incluir en el fichero de configuración del proyecto de Test, ya que cuando se lanza la ejecución de las pruebas el fichero de configuración que se usa es el que está con el proyecto de Test.
Una vez que generamos el fichero a disco, ya podemos comprobar si éste se mandado realmente. Para ello añadiremos la siguiente línea a nuestra prueba unitaria:
Assert.AreEqual(expected,Directory.GetFiles(@"C:MailMessages","*.eml").Length);
El fichero generado es un fichero de correo, con extension eml, que tiene el siguiente aspecto:
Ya por último, vamos a utilizar los métodos de inicialización para asegurarnos de que el entorno está como necesitamos antes de lanzar la prueba y que lo dejamos limpio después de finalizar la ejecución de las mismas.
- [MyClassInitialize] Si no existe el directorio destino de los mensajes lo creamos. Si existe, nos aseguramos de que no tenga ficheros eml de ejecuciones anteriores.
- [MyClassCleanup] Al finalizar las pruebas, eliminamos el directorio.
- [MyTestCleanup] Después de la ejecución de cada prueba eliminamos el fichero eml que ha creado la prueba.
[ClassInitialize()] public static void MyClassInitialize(TestContext testContext) { if (Directory.Exists(@"C:MailMessages")) Directory.CreateDirectory(@"C:MailMessages"); else DeleteMailMessages(); } [ClassCleanup()] public static void MyClassCleanup() { if (Directory.Exists(@"C:MailMessages")) Directory.Delete(@"C:MailMessages", true); } [TestInitialize()] public void MyTestInitialize() { } [TestCleanup()] public void MyTestCleanup() { DeleteMailMessages(); } private static void DeleteMailMessages() { if (Directory.Exists(@"C:MailMessages")) { string[] files = Directory.GetFiles(@"C:MailMessages","*.eml"); foreach ( string file in files ) File.Delete(file); } }
Gracias por tu aportación