Как выполнить модульное тестирование метода Initialize () System.Web.Mvc.Controller? - PullRequest
1 голос
/ 18 февраля 2011

Я хотел бы провести модульное тестирование метода Initialize объекта Controller.Метод Initialize () в основном извлекает идентификатор игрока из коллекции файлов cookie объекта запроса и извлекает текущий объект игрока из базы данных.Затем объект проигрывателя сохраняется в свойстве CurrentPlayer объекта контроллера.У меня есть следующий код для модульного теста.Этот тест в основном написан для метода Index () контроллера:

[Test]
public void Index_ReturnsJsonResult ()
{
   var _gameRepositoryMock = GameRepositoryCreator.Create (5);

   var _formsAuthenticationMock = new Mock<IFormsAuthentication> ();

   var _chooseOpponentController = new ChooseOpponentController (_gameRepositoryMock.Object, _formsAuthenticationMock.Object);


    var cookie = new HttpCookie (cookieName);
    cookie.Value = player.PlayerID + "_encrypted";

    var cookies = new HttpCookieCollection ();
    cookies.Add (cookie);

    var httpRequestMock = new Mock<HttpRequestBase> ();
    httpRequestMock.Setup (x => x.Cookies).Returns (cookies);
    httpRequestMock.Setup (x => x.IsAuthenticated).Returns (true);

    var httpContextMock = new Mock<HttpContextBase> ();
    httpContextMock.Setup (x => x.Request).Returns (httpRequestMock.Object);

    var rd = new RouteData ();
    rd.Values.Add ("action", "Index");
    rd.Values.Add ("controller", "ChooseOpponent");

    var requestContext = new RequestContext (httpContextMock.Object, rd); 

    _formsAuthenticationMock.Setup (x => x.Decrypt (cookie.Value)).Returns (player.PlayerID + "");   

    (_chooseOpponentController as IController).Execute (requestContext);

    Assert.IsNotNull (_chooseOpponentController.CurrentPlayer);

    ... // test other things for the Index () method
}

Метод Index () объявлен как:

 [Authorize, SavePlayerStatus(Order=2), CommitChanges(Order=1)]
 public ActionResult Index ()
 { ... }

Метод Initialize () выполнен успешноно после этого я получаю исключение со следующим сообщением: «Ссылка на объект не установлена ​​на экземпляр объекта.», и трассировка стека выглядит так:

at System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath(VirtualPath virtualPath, Boolean& keyFromVPP)
at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
at System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.FileExists(String virtualPath)
at System.Web.Mvc.BuildManagerViewEngine.FileExists(ControllerContext controllerContext, String virtualPath)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromGeneralName(ControllerContext controllerContext, List`1 locations, String name, String controllerName, String areaName, String cacheKey, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache)
at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.<FindView>b__b(IViewEngine e)
at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths)
at System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext, String viewName, String masterName)
at System.Web.Mvc.ViewResult.FindView(ControllerContext context)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass1c.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

Любая помощь приветствуется.

1 Ответ

3 голосов
/ 18 февраля 2011

Вызывая Execute, вы, по сути, вызываете весь конвейер MVC.Это включает логику просмотра представления, которая пытается перейти на диск и найти ваши файлы представления.Неисправная часть - это система компиляции ASP.NET, которая не инициализирована должным образом.

Для модульного теста вы выполняете слишком много.Я написал бы 2 теста: один, который проверяет, что метод Index делает правильные вещи, и один, который проверяет, что метод Initialize делает правильные вещи.Все остальное (тот факт, что Initialize вызывается перед методом действия и т. Д.) - это MVC-соединение, о котором вам не нужно беспокоиться.

...