You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core测试Action方法时如何Mock Session

测试AzureReportsController的ResourcesCustomReports方法:Session Mock方案

问题背景

作为Mock和测试领域新手,测试AzureReportsController的ResourcesCustomReports Action时遇到Session相关报错。该Action会生成Guid作为键,将文件字节数组存入Session,我已初始化控制器并设置DefaultHttpContext,但调用Session方法时出错,需要Mock Session以通过返回结果非空的断言。

原测试代码

var azureReportControllerUnderTest = new AzureReportsController(mockIlogger.Object, mockPrismRepository.Object, mockReportRepository.Object);

azureReportControllerUnderTest.ControllerContext = new ControllerContext
{
    HttpContext = new DefaultHttpContext(),
};

azureReportControllerUnderTest.ControllerContext.HttpContext.Request.Headers.Add(HeaderNames.Cookie, selectedTenantCookie);
azureReportControllerUnderTest.HttpContext.Session.Set(handle, memoryStream.ToArray());
azureReportControllerUnderTest.HttpContext.Session.Get(handle);

目标Action代码

[HttpGet]
public IActionResult ResourcesCustomReports(DateTime? startingDate, DateTime? endingDate)
{
    var selectedTenant = this.GetCurrentTenant();
    var fileName = $"resources_report_tenant_id_{selectedTenant}.xlsx";
    var workbook = this.reportsRepository.GetCustomDateResources(selectedTenant, startingDate, endingDate);
    string handle = Guid.NewGuid().ToString();

    using (MemoryStream memoryStream = new MemoryStream())
    {
        workbook?.SaveAs(memoryStream);
        memoryStream.Position = 0;
        this.HttpContext.Session.Set(handle, memoryStream.ToArray());
    }

    return this.Json(new { FileGuid = handle, FileName = fileName });
}

断言代码

var result=azureReportControllerUnderTest.ResourcesCustomReports(to, from);
Assert.IsNotNull(result);

解决方案

核心问题

DefaultHttpContext的默认Session未初始化,直接调用Set/Get会抛出异常,必须模拟一个可用的ISession实例。

实现步骤

  • 用Moq模拟ISession:模拟Session的Set和Get方法,无需真实存储逻辑,只需保证方法正常执行。
  • 挂载Mock的Session到HttpContext:替换DefaultHttpContext的Session属性为Mock实例。
  • 确保GetCurrentTenant返回有效值:如果该方法依赖请求信息,提前配置好对应请求头或状态,避免空引用影响后续逻辑。

修改后的完整测试代码

// 初始化Mock依赖
var mockIlogger = new Mock<ILogger<AzureReportsController>>();
var mockPrismRepository = new Mock<IPrismRepository>();
var mockReportRepository = new Mock<IReportRepository>();

// 模拟GetCurrentTenant返回的租户ID
var selectedTenantId = "test-tenant-id";
var selectedTenantCookie = $"TenantId={selectedTenantId}";

// 模拟ISession
var mockSession = new Mock<ISession>();
// 模拟Set方法,无需实际存储
mockSession.Setup(s => s.Set(It.IsAny<string>(), It.IsAny<byte[]>()))
           .Verifiable();
// 模拟Get方法,按需返回字节数组
mockSession.Setup(s => s.Get(It.IsAny<string>()))
           .Returns((string key) => null);

// 初始化控制器并配置HttpContext
var azureReportControllerUnderTest = new AzureReportsController(mockIlogger.Object, mockPrismRepository.Object, mockReportRepository.Object);

var httpContext = new DefaultHttpContext();
httpContext.Request.Headers.Add(HeaderNames.Cookie, selectedTenantCookie);
// 挂载Mock的Session
httpContext.Session = mockSession.Object;

azureReportControllerUnderTest.ControllerContext = new ControllerContext
{
    HttpContext = httpContext
};

// 调用Action并断言
var to = DateTime.Now;
var from = DateTime.Now.AddDays(-7);
var result = azureReportControllerUnderTest.ResourcesCustomReports(to, from);

Assert.IsNotNull(result);
// 可选:验证Session的Set方法是否被调用
mockSession.Verify(s => s.Set(It.IsAny<string>(), It.IsAny<byte[]>()), Times.Once);

内容的提问来源于stack exchange,提问作者Tim Whatley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:05:26