Shawn Mclean
Shawn Mclean

Reputation: 57469

How to set up an email or notification service for asp.net mvc

How do I create an email sending notification service class that I can mock and unit test?

My service is in another layer which is a class library. I'm trying not to import the smtp client, but if this is unavoidable, then its no problem. This is what I have now:

public class EmailNotificationService : INotificationService
{
    private readonly EmailNotification _emailNotification;

    public EmailNotificationService(EmailNotification emailNotification)
    {
        _emailNotification = emailNotification;
    }

    public void Notify()
    {
        using (var mail = new MailMessage())
        {
            //If no replyto was passed in the notification, then make it null.
            mail.ReplyTo = string.IsNullOrEmpty(_emailNotification.ReplyTo) ? null : new MailAddress(_emailNotification.ReplyTo);

            mail.To.Add(_emailNotification.To);
            mail.From = _emailNotification.From;
            mail.Subject = _emailNotification.Subject;
            mail.Body = _emailNotification.Body;
            mail.IsBodyHtml = true;

            //this doesn't seem right.
            SmtpClient client = new SmtpClient();
            client.Send(mail);
        }
    }
}

public class EmailNotification
{
    public EmailNotification()
    {
        To = "";
        ReplyTo = "";
        Subject = "";
        Body = "";
    }
    public string To { get; set; }
    public string ReplyTo { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }

}

Upvotes: 2

Views: 1699

Answers (1)

clyc
clyc

Reputation: 2450

If you don't want to import the System.Net.Mail library, you would have to use an interface. Note that this doesn't really help much for your unit testing though

public interface IEmailSender{
     void Send(EmailNotification emailNotification);
}

and then in your EmailNotificationService class you can add the following property or pass in the IEmailSender in your constructor

private IEmailSender emailSender;

public IEmailSender EmailSender
{
     get{
          if(this.emailSender == null){
               //Initialize new EmailSender using either
               // a factory pattern or inject using IOC 
          }
          return this.emailSender
     }
     set{
          this.emailSender = value;
     }
}

your Notify method would become

public void Notify()
{
    EmailSender.Send(_emailNotification);
}

you would then create a concrete class that implements the IEmailSender interface

public class MyEmailSender: IEmailSender
{
     public void Send(EmailNotification emailNotification)
     {
        using (var mail = new MailMessage())
        {
            //If no replyto was passed in the notification, then make it null.
            mail.ReplyTo = 
                    string.IsNullOrEmpty(_emailNotification.ReplyTo) ? null : 
                    new MailAddress(_emailNotification.ReplyTo);

            mail.To.Add(emailNotification.To);
            mail.From = emailNotification.From;
            mail.Subject = emailNotification.Subject;
            mail.Body = emailNotification.Body;
            mail.IsBodyHtml = true;

            SmtpClient client = new SmtpClient();
            client.Send(mail);
        }
     }
}

Upvotes: 2

Related Questions