如何使用XUnit和Moq测试GetRefusalPdf接口方法?
完善ASP.NET Core Post接口的XUnit+Moq测试用例
首先明确待测试接口的核心逻辑:
- 入参
refusal为null时返回406状态码 - 入参有效时,先记录API请求日志,再调用服务生成PDF流,最后返回带指定文件名的PDF文件
测试前的准备工作
测试类需要模拟控制器的两个依赖项ILoggingFactory和IDispatchRefusalService,同时为控制器配置HttpContext(日志方法需要用到该对象)。
using Xunit; using Moq; using Microsoft.AspNetCore.Mvc; using System.IO; using System; public class DispatchRefusalControllerTests { private readonly Mock<ILoggingFactory> _mockLoggingFactory; private readonly Mock<IDispatchRefusalService> _mockDispatchService; private readonly DispatchRefusalController _controller; public DispatchRefusalControllerTests() { // 初始化Mock依赖 _mockLoggingFactory = new Mock<ILoggingFactory>(); _mockDispatchService = new Mock<IDispatchRefusalService>(); // 创建控制器实例并注入Mock依赖 _controller = new DispatchRefusalController(_mockLoggingFactory.Object, _mockDispatchService.Object); // 配置控制器的HttpContext(满足日志方法的调用要求) _controller.ControllerContext.HttpContext = new DefaultHttpContext(); } }
测试场景1:入参为null时返回406状态码
[Fact] public async Task GetRefusalPdf_Returns406Status_WhenRefusalIsNull() { // 执行接口方法 var result = await _controller.GetRefusalPdf(null); // 断言返回结果的类型和状态码 var statusCodeResult = Assert.IsType<StatusCodeResult>(result); Assert.Equal(StatusCodes.Status406NotAcceptable, statusCodeResult.StatusCode); // 验证依赖方法未被触发(入参为空直接返回,无需执行后续逻辑) _mockLoggingFactory.Verify(f => f.LogApiRequests(It.IsAny<HttpContext>()), Times.Never); _mockDispatchService.Verify(s => s.GenerateEtsRefusalFormAsync(It.IsAny<DispatchRefusal>()), Times.Never); }
测试场景2:入参有效时返回正确的PDF文件结果
[Fact] public async Task GetRefusalPdf_ReturnsValidFileResult_WhenRefusalIsValid() { // 1. 准备测试数据 var testRefusal = new DispatchRefusal { PatientName = "John Doe", RefusalDateTime = new DateTime(2024, 5, 20) }; var testPdfStream = new MemoryStream(); var expectedFileName = $"Refusal-{testRefusal.PatientName}-{testRefusal.RefusalDateTime.ToString("yy-MM-dd")}.pdf"; // 2. 模拟PDF生成服务的返回值 _mockDispatchService.Setup(s => s.GenerateEtsRefusalFormAsync(testRefusal)) .ReturnsAsync(testPdfStream); // 3. 执行接口方法 var result = await _controller.GetRefusalPdf(testRefusal); // 4. 断言返回结果的正确性 var fileResult = Assert.IsType<FileStreamResult>(result); Assert.Equal("application/pdf", fileResult.ContentType); Assert.Equal(expectedFileName, fileResult.FileDownloadName); Assert.Same(testPdfStream, fileResult.FileStream); // 5. 验证依赖方法的调用情况 _mockLoggingFactory.Verify(f => f.LogApiRequests(_controller.HttpContext), Times.Once); _mockDispatchService.Verify(s => s.GenerateEtsRefusalFormAsync(testRefusal), Times.Once); }
关键测试点说明
- 依赖验证:通过Moq的
Verify方法确保日志服务和PDF生成服务被正确调用(调用次数、传入参数匹配) - 结果断言:不仅验证返回结果的类型,还要检查ContentType、文件名、流对象的一致性
- 边界场景覆盖:覆盖入参为null的异常分支,确保接口的错误处理逻辑符合预期
内容的提问来源于stack exchange,提问作者user14525299
相关产品推荐
相关产品推荐

