简体   繁体   English

如何测试与ModelState一起使用的ActionFilterAttributes?

[英]How do I test ActionFilterAttributes that work with ModelState?

As suggested by (among others) Kazi Manzur Rashid in this blog post , I am using ActionFilterAttributes to transfer model state from one request to another when redirecting. 正如(其中包括)Kazi Manzur Ra​​shid在这篇博客文章中所建议的那样,我在使用ActionFilterAttributes在重定向时将模型状态从一个请求转移到另一个请求。

However, I find myself unable to write a unit test that test the behavior of these attributes. 但是,我发现自己无法编写测试这些属性行为的单元测试。 As an example, this what I want the test for the ImportModelStateAttribute to do: 举个例子,这就是我想要ImportModelStateAttribute的测试:

  1. Setup the filterContext so that TempData[myKey] contains some fake "exported" ModelState (that is, a ModelStateDictionary I create myself, and add one error to) 设置filterContext以便TempData[myKey]包含一些虚假的“导出” ModelState (也就是我自己创建的ModelStateDictionary ,并添加一个错误)
  2. Make ModelState contain one model error. 使ModelState包含一个模型错误。
  3. Call OnActionExecuting . 调用OnActionExecuting
  4. Verify the two dictionaries are merged, and ModelState now contains both errors. 验证两个词典是否已合并, ModelState现在包含两个错误。

I'm at a loss already on the first step. 我已经迈出了第一步。

EDIT: 编辑:
Yes, I've tried mocking ActionFilterAttribute with Moq, but I get errors stating 是的,我已经尝试用Moq模拟ActionFilterAttribute ,但是我收到错误说明

Invalid setup on non-overridable member 不可覆盖的成员上的设置无效

for both TempData and ModelState . 对于TempDataModelState

Tomas, You do not have to mock the filterContext, you can create the real object for testing the action filter, the same goes for the model state, these are poco objects. Tomas,您不必模拟filterContext,您可以创建用于测试动作过滤器的真实对象,同样适用于模型状态,这些是poco对象。 Only thing that you have to mock is the HttpContext (if needed). 只有你必须模拟的是HttpContext(如果需要)。

[Fact]
public void Should_import_complete_view_data()
{
    var attribute = new ImportViewDataFromTempDataAttribute();

    var httpContext = new Mock<HttpContextBase>();
    var requestContext = new RequestContext(httpContext.Object, new RouteData());

    var previousModel = new object();
    var previousViewData = new ViewDataDictionary(previousModel) {{"foo", "bar"}};

    previousViewData.ModelState.AddModelError("foo", "bar");

    var controller = new Mock<ControllerBase>();
    controller.Object.ViewData = new ViewDataDictionary();
    controller.Object.TempData = new TempDataDictionary { { attribute.Key, previousViewData } };

    var controllerContext = new ControllerContext(requestContext, controller.Object);
    var actionContext = new ActionExecutingContext(controllerContext, new Mock<ActionDescriptor>().Object, new Dictionary<string, object>());

    attribute.OnActionExecuting(actionContext);

    Assert.True(actionContext.Controller.ViewData.ContainsKey("foo"));
    Assert.True(actionContext.Controller.ViewData.ModelState.ContainsKey("foo"));
    Assert.Same(previousModel, actionContext.Controller.ViewData.Model);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM