Pruebas unitarias: Probando el envío de correos electrónicos

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);
 
En este caso sólo comprobamos que el fichero se haya generado pero podríamos hacer las comprobaciones que consideremos. Por ejemplo, abrir el fichero y comprobar si los datos del mismo coinciden con los parámetros que se le han pasado.

El fichero generado es un fichero de correo, con extension eml, que tiene el siguiente aspecto:

image

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);
    }
}

Ibon Landa

bon Landa lleva más de 15 años dedicado al desarrollo de software. Durante este tiempo ha trabajado en diferentes empresas en las cuáles ha podido trabajar en diferentes entornos y tecnologías. Actualmente está focalizado principalmente en tareas de desarrollo, arquitectura, en las herramientas del ciclo de vida y en todo lo relacionado con la plataforma de Cloud Computing Microsoft Azure, área en el que ha sido reconocido como MVP. Participa de forma activa en la comunidad, escribiendo su blog, manteniendo un portal sobre Microsoft Azure y colaborando con Microsoft y grupos de usuarios en eventos de formación, talleres y giras de producto.

Una respuesta a “Pruebas unitarias: Probando el envío de correos electrónicos”

Deja un comentario

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