How to mock/fake SmtpClient in a UnitTest?

user2900970 picture user2900970 · Nov 14, 2013 · Viewed 16.6k times · Source

I want to use it to fake System.Net.Mail.SmtpClient in a MS-Test UnitTest. Therefor I added a Fakes Assembmly of System.dll. Then I create a ShimsContext and a StubSmtpClient.

using (ShimsContext.Create())
{
   StubSmtpClient client = new StubSmtpClient();               
}

But what do I do with it? The ultimate goal would be to write a Test which expects that the send Method is called with a object of MailMessage.

Answer

Teoman shipahi picture Teoman shipahi · Apr 27, 2015

You can create an interface which will expose functions that will be used from SmtpClient

public interface ISmtpClient   
    {
        void Send(MailMessage mailMessage);
    }

Then create your Concrete class which will do real job.

 public class SmtpClientWrapper : ISmtpClient
    {
        public SmtpClient SmtpClient { get; set; }
        public SmtpClientWrapper(string host, int port)
        {
            SmtpClient = new SmtpClient(host, port);
        }
        public void Send(MailMessage mailMessage)
        {
            SmtpClient.Send(mailMessage);
        }
    }

In your test method now you can mock it and use like;

[TestMethod()]
        public void SendTest()
        {
            Mock<ISmtpClient> smtpClient = new Mock<ISmtpClient>();
            SmtpProvider smtpProvider = new SmtpProvider(smtpClient.Object);
            string @from = "[email protected]";
            string to = "[email protected]";
            bool send = smtpProvider.Send(@from, to);
            Assert.IsTrue(send);
        }