如何为 Core api 控制器测试自动 ModelState 的自定义属性方法验证?

沙哈·肖克拉尼

我想针对给定MyModelDTO测试我的控制器方法

这是我的控制器 Post 方法(简化):

[HttpPost]
public ActionResult Post([FromBody] MyModelDTO itemDTO)
{
    ModelState.Remove($"{nameof(itemDTO)}.{nameof(itemDTO.Id)}");
    if (!ModelState.IsValid)
    {
        return BadRequest();
    }
    //rest of code
}

我的MyModelDTO班级:

public class MyModelDTO
{
    [IsNotEmpty(ErrorMessage = "Guid Id Is Empty")]
    public Guid Id { get; set; }
}

我的习惯ValidationAttribute

public class IsNotEmptyAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;

        var valueType = value.GetType();
        var emptyField = valueType.GetField("Empty");

        if (emptyField == null) return true;

        var emptyValue = emptyField.GetValue(null);

        return !value.Equals(emptyValue);
    }
}

我的问题是如何测试 ModelState 的自定义属性的自动验证

这是我尝试过的:

[Test] public void Post_WhenCalled_ShouldReturnPostResult()
{
    using (var mock = AutoMock.GetLoose())
    {
        //Arrange
        var controller = mock.Create<MyController>();

        //Act
        ActionResult actionResult = controller.Post(new MyModelDTO());

        //Assert... 
     }
}

单元测试工作正常(控制器应该MyModelDTO使用没有参数的参数Id),但看起来它并没有真正模拟 ModelState 的自动验证过程。我怎么知道这个?因为当我尝试做一个缺少Id财产的邮递员时,它会导致"Guid Id Is Empty"消息。它甚至不会在断点处停止。

作为模型绑定过程的一部分,模型验证在控制器之外被调用。这意味着您无法在控制器单元测试中真正测试它。相反,在测试控制器时,如果您想根据模型状态验证控制器的行为,您基本上已经必须模拟模型状态。

您可以在这里做两件事:如果您只想测试您的验证逻辑,那么最好的方法就是直接调用ValidationAttribute所以你不测试控制器,而是测试你的属性。

您可以简单地实例化您的属性,然后运行该Validate方法来测试其行为。只需传递您要验证的对象的实例,您就可以验证它抛出的异常。

另一种解决方案是进行完整的集成测试这样,您就不会对控制器进行单元测试,而是测试整个请求管道,包括控制器和模型验证。对于特定场景,这是确保一切端到端运行的最佳方式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何取消测试API控制器方法

如何创建自定义 api 参数验证属性,该属性在 aspnet core 3 上返回错误请求?

如何从 .net core 2.1 mvc 中的控制器调用自定义身份注册方法

如何在服务中获取控制器的ModelState以进行验证

Web API控制器内的自定义属性

自定义验证器属性在单元测试中有效,但在 web api 控制器中无效?

验证之前的ASP.NET Core 2.0 ModelState筛选器?

是否可以在ASP.NET Core中使用自定义ModelState验证提供程序?

.Net core web api - 如何在控制器中实现 PUT、POST 和 DELETE 方法?

如何为 Asp.NET Core 3.0 的自定义 RequiredIf 属性设置客户端验证

在API控制器中调用自定义方法

Rails 4 + Rspec:使用REST API的父控制器进行自定义身份验证的DRY测试吗?

如何正确配置模拟依赖项以使用 Autofac 测试 Web Api (ASP.NET Core) 控制器

如何在.net core 2.0中创建自定义路由控制器

全局验证所有控制器的ModelState.IsValid

ASP.NET Core Web API中用于整数值的自定义模型验证器

Dotnet Core API-获取控制器方法的URL

如何在.NET Core中测试控制器

如何在sails.js 中对API 请求调用自定义控制器?

在.NET Core Web API中使用自定义属性进行JWT身份验证

在单元测试.NET Core Web API中检查ModelState内容

如何为代理控制器设置Web API路由?

如何在Asp.Net Core MVC项目中为Swagger文档明确定义API控制器路径

如何重新绑定MVC Core 2 ModelState

通过ActionExecutingContext从控制器.Net Core获取自定义属性

Net Core自定义控制器

如何使用 xUnit 测试 API 控制器

如何为我的 Laravel 自定义包的控制器创建别名

如何为page_layout设置自定义控制器