Asp.net core 2 XUnit -- 抛出异常的单元测试 MVC 控制器

Asp.net core 2 XUnit -- Unit Test MVC controller that throws exception

我正在尝试对 return 是 IActionResult 但在某些情况下也可能引发异常的控制器进行单元测试。我 运行 遇到的问题是我不确定如何调用它,因为 Assert 抛出一个错误,您无法从 IActionResult 转换为 Action。

我将如何测试以下语句?

 Assert.Throws<Exception>(await controller.SendEmail(email)); //how to test this

我查看了 Microsoft 测试控制器文档,但没有找到相关内容。我看到的大多数测试异常示例都是针对访问存储库或服务之类的。

我知道我可以 return 错误请求或重定向到带有错误消息的页面。但是我想要完成的事情可能吗?

我的 HomeController 方法

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> SendEmail(EmailModel emailModel)
        {
            if(!ModelState.IsValid)
            {
                return View("Index",emailModel);
            }

            var response = await _sendEmail.SendEmailMessage(emailModel);

            if (response != System.Net.HttpStatusCode.Accepted)
            {
                throw new Exception("Email failed to send, please try again later");
            }
            else
            {
                TempData["message"] = $"Email has been sent";
            }

            return RedirectToAction("Index");
        }

用于安排的 XUnit HomeControllerTest 构造函数

        private Mock<ISendEmail> mockSendEmail;
        private HomeController controller;

        public HomeControllerShould()
        {
            mockSendEmail = new Mock<ISendEmail>();
            mockSendEmail.Setup(x => x.SendEmailMessage(It.IsAny<EmailModel>())).ReturnsAsync(HttpStatusCode.Accepted);
            controller = new HomeController(mockSendEmail.Object);
        }

发送电子邮件的 XUnit 测试

 [Fact]
    public async Task SendEmailActionThrowsExceptionOnEmailFailure()
    {
        mockSendEmail.Setup(x => x.SendEmailMessage(It.IsAny<EmailModel>())).ReturnsAsync(HttpStatusCode.InternalServerError);
        var email = new EmailModel();

        Assert.Throws<Exception>(await controller.SendEmail(email)); //how to test this
    }

Assert.Throws 需要一个函数。你可以使用 ThrowsAsync.

[Fact]
public async Task SendEmailActionThrowsExceptionOnEmailFailure()
{
    mockSendEmail.Setup(x => x.SendEmailMessage(It.IsAny<EmailModel>()))
        .ReturnsAsync(HttpStatusCode.InternalServerError);

    var email = new EmailModel();

     await Assert.ThrowsAsync<Exception>(() => controller.SendEmail(email)); 
}

仅供参考:我们通常不会 return HttpStatusCode 来自服务层,例如电子邮件服务,但我会让您决定。