[英]Unit test FluentEmail in .NET 5 using xUnit and Moq
I'm trying to unit test FluentEmail , but I keep getting null
in the send response.我正在尝试对FluentEmail进行单元测试,但我一直在发送响应中收到
null
。
This is how it's set up in the ConfigureServices
method:这是它在
ConfigureServices
方法中的设置方式:
// Set email service using FluentEmail
services.AddFluentEmail("sender@test.com")
// For Fluent Email to find _Layout.cshtml, just mention here where your views are.
.AddRazorRenderer(@$"{Directory.GetCurrentDirectory()}/Views/")
.AddSmtpSender("smtp.somecompanyname.com", 25)
.AddSmtpSender(new System.Net.Mail.SmtpClient() { });
Now the email service looks like this:现在 email 服务看起来像这样:
public class FluentEmailService : IFluentEmailService
{
private readonly IFluentEmail _fluentEmail;
private readonly ILogger<FluentEmailService> _logger;
public FluentEmailService(ILogger<FluentEmailService> logger, IFluentEmail fluentEmail)
{
_logger = logger;
_fluentEmail = fluentEmail;
}
public async Task<SendResponse> SendEmailAsync<TModel>(string subject, string razorTemplatePath, TModel model, string semicolonSeparatedEmailRecipients)
{
try
{
var sendResponse = await _fluentEmail
.To(semicolonSeparatedEmailRecipients)
.Subject(subject)
.UsingTemplateFromFile(razorTemplatePath, model)
.SendAsync();
return sendResponse;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send email. Check exception for more information.");
return new SendResponse() { ErrorMessages = new string[] { ex.Message } };
}
}
}
My test method looks like this:我的测试方法如下所示:
[Fact]
public async Task Can_Verify_FluentEmail_WORKS_Async()
{
// ARRANGE
var mockFluentEmail = new Mock<IFluentEmail>();
mockFluentEmail.Setup(m => m.To(It.IsAny<string>())).Returns(mockFluentEmail.Object);
mockFluentEmail.Setup(m => m.Subject(It.IsAny<string>())).Returns(mockFluentEmail.Object);
mockFluentEmail.Setup(m => m.UsingTemplateFromFile(It.IsAny<string>(), It.IsAny<It.IsAnyType>(), It.IsAny<bool>())).Returns(mockFluentEmail.Object);
//Create FluentEmail service using fake logger and IFluentEmail
var fakeLogger = Mock.Of<ILogger<FluentEmailService>>();
var fluentEmailService = new FluentEmailService(fakeLogger, mockFluentEmail.Object);
// ACT
var sendResponse = await fluentEmailService.SendEmailAsync("Test Subject", "Some Path", It.IsAny<It.IsAnyType>(), "Some Recipient");
// ASSERT
Assert.NotNull(sendResponse);
Assert.True(sendResponse.Successful);
mockFluentEmail.Verify(f => f.To("Some Recipient"), Times.Once(), "Recipient should be set as: 'Some Recipient'.");
mockFluentEmail.Verify(f => f.Subject("Test Subject"), Times.Once, "Subject should be set as: 'Test Subject'.");
mockFluentEmail.Verify(f => f.UsingTemplateFromFile("Some Path", It.IsAny<It.IsAnyType>(), It.IsAny<bool>()), Times.Once, "Path should be set as: 'Some Path'.");
mockFluentEmail.Verify(f => f.SendAsync(null), Times.Once, "1 email should be sent.");
}
The test always fails because I get null
as the sendResponse
.测试总是失败,因为我得到
null
作为sendResponse
。
Can someone please tell me if I'm doing this correctly?有人可以告诉我我这样做是否正确吗?
It is probably because of last function call SendAsync
is not mocked and therefore returning null by default.这可能是因为最后一个 function 调用
SendAsync
没有被模拟,因此默认返回 null。
Since it is async call, it makes sense to use ReturnsAsync
instead of Returns
.由于它是异步调用,因此使用
ReturnsAsync
而不是Returns
是有意义的。
ReturnsAsync
should also return an actual SendResponse
: ReturnsAsync
还应该返回实际的SendResponse
:
//...
SendResponse expectedSendResponse = new SendResponse();
mockFluentEmail
.Setup(m => m.SendAsync(null))
.ReturnsAsync(expectedSendResponse);
//...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.