如何为此操作筛选器编写单元测试


public MyContext _db;
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
   if (_db == null || !_db.ChangeTracker.HasChanges())
   {
      return;
   }
   try
   {
      _db.SaveChanges();
   }
   catch
   {
   }
}

这是我的 wep api 项目的操作过滤器。 _db每个请求注入此筛选器的上下文对象。我的观点是在服务层中完成所有处理后调用 SaveChanges() 方法一次。我的问题是如何测试这个过滤器?我如何模拟可能发生在任何控制器或服务层中的异常情况,以及当异常抛出 saveChanges() 时从未调用?如何设置在应用程序内任何地方发生异常的情况?

上周,我一直在为我的 WebAPI 2 操作过滤器做同样的事情。

我有一个操作过滤器来验证我的 ModelState,如果出现任何错误,它会抛出一个包含 200 HTTPcode 的错误列表。

操作如下所示:

 public class ModelValidationActionFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var modelState = actionContext.ModelState;
            if (!modelState.IsValid)
            {
                actionContext.Response = ...
            }
        }
    }

单元测试

var httpControllerContext = new HttpControllerContext
            {
                Request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/someUri")
                {
                    Content = new ObjectContent(typeof(MyModel),
                        new MyModel(), new JsonMediaTypeFormatter())
                },
                RequestContext = new HttpRequestContext()
            };
            httpControllerContext.Request = new HttpRequestMessage();
            httpControllerContext.Request.SetConfiguration(new HttpConfiguration());
            var httpActionContext = new HttpActionContext { ControllerContext = httpControllerContext };
            var filter = new ModelValidationActionFilterAttribute();
            httpActionContext.ModelState.AddModelError("*", "Invalid model state");
            // act
            filter.OnActionExecuting(httpActionContext);
            // assert
            httpActionContext.Response.ShouldNotBe(null);
            httpActionContext.Response.ShouldBeOfType(typeof (HttpResponseMessage));
            var result = httpActionContext.Response.Content.ReadAsStringAsync().Result;
            BaseServiceResponse<object> resultResponse =
                JsonConvert.DeserializeObject<BaseServiceResponse<object>>(result);
            resultResponse.Data.ShouldBe(null);
            resultResponse.Messages.Count.ShouldBe(1);
            resultResponse.Messages.First().Description.ShouldBe("Invalid model state");

在您的情况下,您需要使用 IDbContext 接口模拟数据库上下文 - 请参阅此处:http://aikmeng.com/post/62817541825/how-to-mock-dbcontext-and-dbset-with-moq-for-unit

如果在执行请求时发生未经处理的异常,则 actionExecutedContext 上的 Exception 属性将包含异常。这是框架的一部分,不是你需要测试的东西。在测试中,您可以简单地手动设置 Exception 属性,并断言该属性采取正确的操作。

[Fact]
public void Saves_data_on_failure()
{
    var mockDbContext = new Mock<IDbContext>();
    var myAttribute = new MyAttribute(mockDbContext.Object);
    var executionContext = new HttpActionExecutedContext
    {
        Exception = new Exception("Request failed.")
    };
    myAttribute.OnActionExecuted(executionContext);
    mockDbContext.Verify(d => d.SaveChanges());
}

您可能还需要考虑是否要为所有类型的异常保存数据。数据可能处于无效/未知状态。

相关内容

  • 没有找到相关文章

最新更新