2

このブログ投稿で (とりわけ) Kazi Manzur Ra​​shid が示唆しているようActionFilterAttributesに、リダイレクト時にモデルの状態をあるリクエストから別のリクエストに転送するために使用しています。

ただし、これらの属性の動作をテストする単体テストを作成することはできません。例として、これは のテストで実行したいことImportModelStateAttributeです。

  1. 偽の「エクスポート」filterContextを含むようにセットアップします(つまり、自分で作成し、エラーを1つ追加します)TempData[myKey]ModelStateModelStateDictionary
  2. ModelState1 つのモデル エラーを含むようにします。
  3. コールしOnActionExecutingます。
  4. 2 つの辞書がマージされ、両方のエラーModelStateが含まれていることを確認します。

私はすでに最初のステップで途方に暮れています。

編集:
はい、ActionFilterAttributeMoq でモックしようとしましたが、次のエラーが表示されます

上書き不可能なメンバーの設定が無効です

TempDataとの両方についてModelState

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 に答える