加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

unit-testing – 单元测试自定义验证过滤器

发布时间:2020-12-16 07:20:03 所属栏目:asp.Net 来源:网络整理
导读:我有以下属性: public class ValidateModelAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext actionContext) { if (actionContext.ModelState.IsValid == false) { actionContext.Response = actionContext.
我有以下属性:

public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.ModelState.IsValid == false)
            {
                actionContext.Response = actionContext.Request.CreateErrorResponse(
                    HttpStatusCode.BadRequest,actionContext.ModelState);
            }
        }
    }

我有这个通用的扩展方法,用于确定属性是否应用于方法

public static bool ActionHasFilter(this ApiController controller,string action,Type filter)
    {
        var controllerType = controller.GetType();
        var method = controllerType.GetMethod(action);

        object[] filters = method.GetCustomAttributes(filter,true);

        return filters.Any(x=>x.GetType() == filter);

    }

我的问题是如何在不测试控制器动作的情况下测试属性是否真实有效?

假设我有以下实体

public class UserViewModel
{
     [Required]
     public string Name {get; set;}
     [Required]
     [EmailAddress]
     public string Email {get;set;
}

我将如何模拟上下文并检查模型是否有效?

我正在使用Nunit和Moq.

解决方法

Spock’s solution是在正确的轨道上,但在代码上有点过于侵入,因为它使ValidateModelAttribute类依赖于TestableHttpActionContext.我的实现使用一个公共属性,用于“注入”单元测试的Request对象,而实现为属性继续使用ActionContext中的Request对象:

public class ValidateModelAttribute : ActionFilterAttribute
{
    public HttpRequestMessage TestRequestMessage { get; set; }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        PerformValidation(actionContext,TestRequestMessage ?? actionContext.Request);
    }

    private void PerformValidation(HttpActionContext actionContext,HttpRequestMessage request)
    {
        if (actionContext.ModelState.IsValid == false)
        {
            actionContext.Response = request.CreateErrorResponse(HttpStatusCode.BadRequest,actionContext.ModelState);
        }
    }
}

单元测试:

[Test]
public void OnActionExecuting_ValidModel_ResponseIsNotSet()
{
    var actionContext = new HttpActionContext();

    actionContext.ModelState.Clear();

    var attribute = new ValidateModelAttribute { TestRequestMessage = new HttpRequestMessage() };

    attribute.OnActionExecuting(actionContext);

    Assert.IsNull(actionContext.Response);
}

[Test]
public void OnActionExecuting_InvalidModel_ResponseIsSetToBadRequest()
{
    var actionContext = new HttpActionContext();

    actionContext.ModelState.AddModelError("key","error");

    var attribute = new ValidateModelAttribute() { TestRequestMessage = new HttpRequestMessage() };

    attribute.OnActionExecuting(actionContext);

    Assert.AreEqual(HttpStatusCode.BadRequest,actionContext.Response.StatusCode);
}

请注意,我没有使用实际模型来验证ModelState,因为这超出了单元测试的范围:我们想要测试ModelState的结果,而不是ModelState本身.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读