如何在UnitTest中模拟/伪造SmtpClient?

时间:2013-11-14 06:48:31

标签: c# mstest microsoft-fakes

我想用它在MS-Test UnitTest中伪造System.Net.Mail.SmtpClient。因此我添加了一个Fizz Assembmly of System.dll。然后我创建了ShimsContextStubSmtpClient

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

但是我该怎么做呢? 最终目标是编写一个测试,期望使用MailMessage的对象调用send方法。

4 个答案:

答案 0 :(得分:26)

您可以创建一个接口,该接口将公开将从SmtpClient

中使用的函数
public interface ISmtpClient   
    {
        void Send(MailMessage mailMessage);
    }

然后创建您的Concrete类,它将完成实际工作。

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

现在你可以在你的测试方法中模拟它并使用like;

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

答案 1 :(得分:7)

这不是你问题的真正答案,而是另一种方法:

在app.config中,将smtp设置设置为deliver the mails as files to a local directory。然后,您可以加载该文件并检查断言部分中的内容。

您必须为断言编写更多代码(或者最好创建一些辅助函数),但您不必做任何影响生产代码的事情。

答案 2 :(得分:3)

另一种方法是使用nDumbster

Install-Package nDumbster

它在内存中运行一个Smtp服务器,然后您可以对其进行验证。它将其更多地转换为集成测试,但通常这些值比单元测试更高,因为您要测试SmtpClient用法也是正确的。

答案 3 :(得分:0)

answerTeoman shipahi版本正确处理add()

首先让SmtpClient继承ISmtpClient

IDisposable

然后在public interface ISmtpClient : IDisposable { void Send(MailMessage mailMessage); } 类中实现IDisposable

SmtpClientWrapper

对于此版本的public class SmtpClientWrapper : ISmtpClient { private bool disposed; private readonly SmtpClient smtpClient; public SmtpClientWrapper(string host, int port) { smtpClient = new SmtpClient(host, port); } ~SmtpClientWrapper() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { smtpClient?.Dispose(); } disposed = true; } } protected void CheckDisposed() { if (disposed) { throw new ObjectDisposedException(nameof(SmtpClientWrapper)); } } public void Send(MailMessage mailMessage) { CheckDisposed(); smtpClient.Send(mailMessage); } } ,我删除了SmtpClientWrapper属性,以避免在SmtpClient的setter中替换时SmtpClient个对象未被处置的问题属性。