web-dev-qa-db-ja.com

ASP.NetMVCでカスタムActionFilterを単体テストするにはどうすればよいですか

そのため、主にこのプロジェクトに基づくカスタムActionFilterを作成しています http://www.codeproject.com/KB/aspnet/aspnet_mvc_restapi.aspx

Httpacceptヘッダーを使用してJSONまたはXmlのいずれかを返すカスタムアクションフィルターが必要です。一般的なコントローラーのアクションは次のようになります。

_[AcceptVerbs(HttpVerbs.Get)]
[AcceptTypesAttribute(HttpContentTypes.Json, HttpContentTypes.Xml)]
public ActionResult Index()
{
    var articles = Service.GetRecentArticles();

    return View(articles);
}
_

カスタムフィルターはOnActionExecutedをオーバーライドし、オブジェクト(この例では記事)をJSONまたはXmlとしてシリアル化します。

私の質問は:これをどのようにテストするのですか?

  1. どのようなテストを書きますか?私はTDDの初心者であり、何をテストすべきか、何をテストすべきでないかを100%確信していません。 AcceptsTypeFilterJson_RequestHeaderAcceptsJson_ReturnsJson()AcceptsTypeFilterXml_RequestHeaderAcceptsXml_ReturnsXml()AcceptsTypeFilter_AcceptsHeaderMismatch_ReturnsError406()を思いついた。
  2. Http AcceptヘッダーをテストしているMVCでActionFilterをテストするにはどうすればよいですか?

ありがとう。

24
John

フィルタ自体をテストする必要があります。インスタンスを作成し、テストデータを使用してOnActionExecuted()メソッドを呼び出して、結果を確認するだけです。コードを可能な限り引き離すのに役立ちます。面倒な作業のほとんどは、個別にテストできるCsvResultクラス内で行われます。実際のコントローラーでフィルターをテストする必要はありません。それを機能させることはMVCフレームワークの責任です。

public void AcceptsTypeFilterJson_RequestHeaderAcceptsJson_ReturnsJson()
{
    var context = new ActionExecutedContext();
    context.HttpContext = // mock an http context and set the accept-type. I don't know how to do this, but there are many questions about it.
    context.Result = new ViewResult(...); // What your controller would return
    var filter = new AcceptTypesAttribute(HttpContentTypes.Json);

    filter.OnActionExecuted(context);

    Assert.True(context.Result is JsonResult);
}
27
Ryan

私はちょうど偶然見つけました このブログ投稿 これは私にとって正しい方法のようです、彼は Moq を使用します

編集

さて、この章が行っているのはHTTPContextをモックすることですが、リクエストでContentTypeを設定する必要もあります。

    // Mock out the context to run the action filter.
    var request = new Mock<HttpRequestBase>();
    request.SetupGet(r => r.ContentType).Returns("application/json");

    var httpContext = new Mock<HttpContextBase>();
    httpContext.SetupGet(c => c.Request).Returns(request.Object);

    var routeData = new RouteData(); //
    routeData.Values.Add("employeeId", "123");

    var actionExecutedContext = new Mock<ActionExecutedContext>();
    actionExecutedContext.SetupGet(r => r.RouteData).Returns(routeData);
    actionExecutedContext.SetupGet(c => c.HttpContext).Returns(httpContext.Object);

    var filter = new EmployeeGroupRestrictedActionFilterAttribute();

    filter.OnActionExecuted(actionExecutedContext.Object);

注-私はこれを自分でテストしていません

15
Luke T O'Brien