2

正如(除其他外)Kazi Manzur Ra​​shid 在这篇博文中所建议的那样,我ActionFilterAttributes在重定向时用于将模型状态从一个请求转移到另一个请求。

但是,我发现自己无法编写单元测试来测试这些属性的行为。例如,这是我想要测试的ImportModelStateAttribute

  1. 设置filterContext包含TempData[myKey]一些假“导出”ModelState的内容(即ModelStateDictionary我自己创建的,并添加一个错误)
  2. 使ModelState包含一个模型错误。
  3. 打电话OnActionExecuting
  4. 验证两个字典是否已合并,ModelState现在包含两个错误。

我已经在第一步不知所措了。

编辑:
是的,我试过ActionFilterAttribute用 Moq 模拟,但我收到错误说明

不可覆盖成员上的无效设置

对于TempDataModelState

4

1 回答 1

8

Tomas,您不必模拟 filterContext,您可以创建真实的对象来测试动作过滤器,模型状态也是如此,这些是 poco 对象。唯一需要模拟的是 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);
}
于 2010-04-10T23:48:16.593 回答