单元测试自定义验证过滤器 [英] Unit Testing a Custom Validation Filter

查看:195
本文介绍了单元测试自定义验证过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下属性:

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

我有这样的通用扩展方法来确定属性是否被应用于方法还是不

I have this generic extension method for Determining whether the attribute is applied to a method or not

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);

    }

我的问题是我如何去测试属性是否实际工作或没有,没有测试控制器动作?

My problem is how do i go about testing whether the attribute actually works or not, without testing the controller action?

让我们说我有以下实体

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

我将如何去嘲讽的背景和检查模型是否有效?

How would i go about mocking the context and checking whether the model is valid?

我使用NUnit和起订量。

I'm using Nunit and Moq.

推荐答案

Spock的解决方案是在正确的轨道上,但是在code有点太侵入,因为它使 ValidateModelAttribute 类依赖于 TestableHttpActionContext 。我的实现使用将用于注入为单元测试的请求对象的公共财产,而作为属性的实施,继续使用请求从对象中的 ActionContext中

Spock's solution is on the right track, but is a bit too invasive on the code, because it makes the ValidateModelAttribute class dependent on TestableHttpActionContext. My implementation uses a public property that will be used to "inject" the Request object for the Unit Tests, while the implementation as attribute continues to use the Request object from the ActionContext:

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 本身。 ; - )

Please note that I'm not using an actual model to validate the ModelState, because that's out of scope for the Unit Tests: We want to test the ModelState's outcome, not the ModelState itself. ;-)

这篇关于单元测试自定义验证过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆