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

.NET Framework转.NET Core 2.1:自定义过滤器属性单元测试适配

在.NET Core 2.1中测试自定义ActionFilterAttribute的正确姿势

你遇到的问题本质是.NET Core MVC和.NET Framework MVC的Action上下文类结构差异导致的——原来的HttpActionContext、HttpControllerContext这些类型在.NET Core里已经被重构替换了,不过测试自定义ActionFilterAttribute的思路完全可行,只需要适配新的API来构建测试上下文。

下面给你一套适配.NET Core 2.1的测试代码,完美对应你原来的测试逻辑(沿用你熟悉的MSTest风格):

测试类初始化与上下文构建

private ActionExecutingContext _successContext;
private ActionExecutingContext _failContext;

[TestInitialize]
public void Initialize()
{
    // 1. 构建基础HTTP上下文与控制器上下文
    var httpContext = new DefaultHttpContext();
    var controllerContext = new ControllerContext
    {
        HttpContext = httpContext
    };

    // 2. 构建Action描述器:.NET Core上下文必须依赖这个,用空测试Controller填充即可
    var actionDescriptor = new ControllerActionDescriptor
    {
        ControllerTypeInfo = typeof(DummyTestController).GetTypeInfo(),
        ActionName = "TestAction"
    };

    // 3. 构建ModelState无错误的成功场景上下文
    var successModelState = new ModelStateDictionary();
    successModelState.Add("TestField", new ModelState());
    _successContext = new ActionExecutingContext(
        controllerContext,
        actionDescriptor,
        new Dictionary<string, object>(), // 无Action参数时传空字典
        new DummyTestController())
    {
        ModelState = successModelState
    };

    // 4. 构建带错误的失败场景上下文
    var failModelState = new ModelStateDictionary();
    failModelState.Add("TestField", new ModelState());
    failModelState.AddModelError("TestField", "Test error message");
    _failContext = new ActionExecutingContext(
        controllerContext,
        actionDescriptor,
        new Dictionary<string, object>(),
        new DummyTestController())
    {
        ModelState = failModelState
    };
}

// 定义一个空的测试用Controller,用于填充上下文的类型信息
private class DummyTestController : Controller { }

测试方法示例

[TestMethod]
public void OnActionExecuting_ModelStateValid_DoesNotSetResult()
{
    // Arrange
    var attribute = new JsonValidationFilterAttribute();

    // Act
    attribute.OnActionExecuting(_successContext);

    // Assert
    Assert.IsNull(_successContext.Result);
}

[TestMethod]
public void OnActionExecuting_ModelStateInvalid_ReturnsBadRequestWithErrors()
{
    // Arrange
    var attribute = new JsonValidationFilterAttribute();

    // Act
    attribute.OnActionExecuting(_failContext);

    // Assert
    var badRequestResult = _failContext.Result as BadRequestObjectResult;
    Assert.IsNotNull(badRequestResult);
    Assert.AreEqual((int)HttpStatusCode.BadRequest, badRequestResult.StatusCode);
    
    var errorMessages = badRequestResult.Value as IEnumerable<string>;
    Assert.IsNotNull(errorMessages);
    Assert.AreEqual("Test error message", errorMessages.First());
}

关键差异说明

对比你原来的.NET Framework测试代码,核心变化点:

  • 用ActionExecutingContext替代了HttpActionContext,这是.NET Core MVC中Action过滤器的标准上下文类型
  • HttpControllerContext被替换为ControllerContext,构建时需要传入DefaultHttpContext模拟HTTP请求环境
  • 必须提供ActionDescriptor,因为.NET Core的上下文依赖这个识别当前Action信息,用空测试Controller填充即可
  • 验证结果时,不再检查Response,而是检查Result属性,对应你Attribute里的BadRequestObjectResult逻辑

这种测试自定义ActionFilter的方法在.NET Core里完全适用,只要按照新的API构建好上下文对象,就能正常验证你的Attribute逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:58:12