我正在为下面的通信服务类编写单元测试用例。我有以下接口通信服务。 我想为 CommunicationService 中存在的 SendMail 方法编写 Nunit 或单元测试,但不发送邮件。 (smtpClient.Send(mailMessage))
public interface ICommunicationService
{
bool SendMail(string mailSender, IEnumerable<string> recipients, IEnumerable<string> cc, string subject, string mailContent, string senderPass);
}
继承接口的类
public class CommunicationService : ICommunicationService
{
private readonly ILogger<CommunicationService> _logger;
public CommunicationService(
ILogger<CommunicationService> logger)
{
_logger = logger;
}
此方法使用SmtpClient发送邮件
public bool SendMail(string mailSender, IEnumerable<string> recipients, IEnumerable<string> cc, string subject, string mailContent, string senderPass)
{
MailMessage mailMessage = new MailMessage
{
Subject = subject,
Body = mailContent,
From = new MailAddress(mailSender, "XXXX"),
IsBodyHtml = true
};
var recipientsList = recipients.ToList();
if (!recipientsList.Any())
{
_logger.LogWarning("Mail not sent, no recipients specified");
}
foreach (var address in recipientsList)
{
mailMessage.To.Add(address);
}
if (cc != null)
{
foreach (string address in cc)
{
mailMessage.CC.Add(address);
}
}
NetworkCredential networkCredential = new NetworkCredential(mailSender, senderPass);
try
{
SmtpClient smtpClient = new SmtpClient
{
Host = "smtp.office365.com",
Port = 587,
EnableSsl = true,
UseDefaultCredentials = false,
Credentials = networkCredential,
DeliveryMethod = SmtpDeliveryMethod.Network,
Timeout = 20000,
};
smtpClient.Send(mailMessage);
return true;
}
catch (Exception exception)
{
_logger.LogError(exception.Message, exception);
return false;
}
}
}
在运行单元测试用例时,我遇到了相同的错误。如何模拟 smtpclient.send() 'SMTP 服务器需要安全连接,或者客户端未经过身份验证。服务器响应为:5.7.57 客户端未经过身份验证,无法发送邮件。错误:535 5.7.3 身份验证失败
这是我尝试过的代码。这是单元测试用例
public void SendMail_SuccessfullySendsMail_ReturnsTrue()
{
// Arrange
var mailSender = "[email protected]";
var recipients = new List<string> { "[email protected]", "[email protected]" };
var cc = new List<string> { "[email protected]", "[email protected]" };
var subject = "Test Subject";
var mailContent = "Test Body";
var senderPass = "your-password";
// Create an instance of your MailSender class
var mailSenderInstance = new CommunicationService(logger.Object);
// Act
var result = mailSenderInstance.SendMail(mailSender, recipients, cc, subject, mailContent, senderPass);
// Assert
Assert.IsTrue(result);
}
这是编写的单元测试用例,但它不起作用。我从 nunit 测试用例中收到身份验证不成功的消息。
你可以像这样重写你的类:
public class CommunicationService: ICommunicationService
{
private readonly ILogger _logger;
private readonly SmtpClient _client;
public CommunicationService( ILogger logger, SmtpClient client)
{
_logger = logger;
_client = client;
}
public bool SendMail(string mailSender, IEnumerable recipients, IEnumerable cc, string subject, string mailContent, string senderPass)
{
// validation part of the old method here
// use client from constructor
_client.Send(mailMessage);
}
}
测试方法:
public void SendMail_SuccessfullySendsMail_ReturnsTrue()
{
// Arrange
var clientMock = new Mock<SmtpClient>();
clientMock.Setup(x => x.Send(/*parameters here*/));
var mailSender = "[email protected]";
var recipients = new List<string> { "[email protected]", "[email protected]" };
var cc = new List<string> { "[email protected]", "[email protected]" };
var subject = "Test Subject";
var mailContent = "Test Body";
var senderPass = "your-password";
// Create an instance of your MailSender class
var mailSenderInstance = new CommunicationService(logger.Object, smtpClient.Object);
// Act
var result = mailSenderInstance.SendMail(mailSender, recipients, cc, subject, mailContent, senderPass);
// Assert
Assert.IsTrue(result);
}
还有另一个关于模拟 SmtpClient 的线程(可能提供更优雅的解决方案):How to mock/fake SmtpClient in a UnitTest?