2010-05-26 13 views
6

Estoy comenzando con la prueba unitaria y tratando de hacer algo de TDD. He leído bastante sobre el tema y he escrito algunas pruebas. Solo quiero saber si el siguiente es el enfoque correcto.¿Cómo debo probar la unidad enviando correos electrónicos desde un controlador?

Quiero agregar la función habitual de "contáctanos" en mi sitio web. Ya sabes, el usuario completa un formulario con su dirección de correo electrónico, ingresa un breve mensaje y pulsa un botón para enviar el formulario de regreso.

Las carpetas modelo hacen sus cosas y mi método de acción acepta los datos publicados como modelo. El método de acción luego analizaría el modelo y usaría smtp para enviar un correo electrónico al administrador del sitio web indicándole que alguien completó el formulario de contacto en su sitio.

Ahora la pregunta .... Con el fin de probar esto, habría que tener la razón en la creación de una interfaz IMessageService que tiene un método Enviar (emailAddress, mensaje) para aceptar la dirección de correo electrónico y el cuerpo del mensaje. Implementa la inteface en una clase concreta y deja que esa clase se ocupe de cosas smtp y realmente envíe el correo.

Si agrego la interfaz como parámetro al constructor de mi controlador, entonces puedo usar DI e IoC para inyectar la clase concreta en el controlador. Pero cuando pruebas la unidad, puedo crear una versión falsa o simulada de mi IMessageService y hacer afirmaciones sobre eso.

La razón por la que pregunto es porque he visto otros ejemplos de personas que generan interfaces para SmtpClient y luego se burlan de eso. ¿Realmente hay alguna necesidad de ir tan lejos o no estoy entendiendo esto?

Respuesta

2

Aún deberá probar su clase que invoca el programa de correo. Sugiero que tal vez quieras hacer un poco de ambos. Normalmente creo una interfaz IMailClient y un contenedor alrededor de SmtpClient que implementa la interfaz. Utilice (e inyecte) la interfaz en una clase de proxy que sepa cómo construir el mensaje y enviarlo (puede tener varios métodos de fábrica que pueden construir múltiples tipos diferentes de mensajes). El ajuste alrededor del SmtpClient realmente debería ser solo eso, por lo tanto, hay poca necesidad de probarlo en unidades. Usted puede burlarse de su shim cuando pruebe la clase proxy y se burle de su clase proxy al probar sus controladores.

+0

Estoy de acuerdo, y probablemente sea útil tan pronto como necesite ese IMailClientAsync t que pueda intercambiar. – Hal

1

El enfoque que describes ha funcionado bien para mí en el pasado. Trabajé en un proyecto que interactuó con la API del servicio web MS Dynamics CRM. Quería probar mi código unitario, pero no deseaba probar el servicio web. Seguí el proceso exacto que describes pero con el servicio web burlado en lugar de la entrega del correo. Funcionó muy bien.

1

Estás en el camino correcto, ese es el enfoque que deberías usar. Probablemente los ejemplos a los que se está refiriendo son personas que lo hacen de la manera difícil/incorrecta ... o son ejemplos de cómo puede tratar con una gran base de código heredada.

La inyección del mecanismo para entregar el mensaje es flexible y se puede reutilizar fácilmente en otros escenarios. Una de estas situaciones es el diagnóstico, si tiene un servidor de desarrollo, probablemente no desee que pegue correos todo el tiempo, al cambiar la clase inyectada puede hacer que salga a un archivo o simplemente a Debug.Write.

ps. todavía se te recomienda que pruebes tu clase SmptDeliver, pero eso sería una prueba de integración enfocada que puedes hacer en esa clase independientemente del resto del código.

1

Creo que estás en el camino correcto. No te preocupes por los servidores SMTP o cualquier otra cosa. Solo prueba lo que necesitas. Deje que las pruebas le digan lo que necesita.Cuando llegue a la prueba del Send(emailAddress, message) real, entonces puede preocuparse por cómo va a enviar el mensaje al administrador.

Cuestiones relacionadas