Модульное тестирование контроллера заканчивается по ошибке - PullRequest
0 голосов
/ 09 декабря 2011

У меня есть приложение MVC 3, которое я пытаюсь выполнить модульное тестирование.Я прочитал пример с этой страницы , который показывает, как издеваться над контроллером.Вот мой тестовый код:

 [TestMethod]
    public void TestAddStudy() {
        var controller = new AdminController();
        var httpContext = FakeHttpContext();
        var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
        controller.ControllerContext = context;

        var request = Mock.Get(controller.Request);
        request.Setup(r => r.Form).Returns(delegate() {
            var nv = new FormCollection();
            nv.Add("Name", "Test Study");
            nv.Add("IsDefault", "selected");
            return nv;
        });

        var result = controller.CreateStudy(request.Object.Form as FormCollection) as ActionResult;

    }

    public static HttpContextBase FakeHttpContext() {
        var httpContext = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();

        httpContext.Setup(ctx => ctx.Request).Returns(request.Object);
        httpContext.SetupGet(ctx => ctx.Request.RequestType).Returns("POST");
        httpContext.Setup(ctx => ctx.Response).Returns(response.Object);
        httpContext.Setup(ctx => ctx.Session).Returns(session.Object);
        httpContext.Setup(ctx => ctx.Server).Returns(server.Object);
        httpContext.SetupGet(ctx => ctx.User.Identity.Name).Returns("testClient");

        return httpContext.Object;
    }

Вот код внутри контроллера:

[HttpPost]
    public ActionResult CreateStudy(FormCollection form) {
        Study newStudy = new Study();
        TryUpdateModel(newStudy);
        newStudy.CreatedBy = CurrentUser;
        newStudy.CreatedOn = DateTime.Now;
        studyRepository.Edit(newStudy, CurrentUser);
        return RedirectToAction("EditStudy", new { id = 1 });
    }

Каждый раз происходит сбой в операторе TryUpdateModel со ссылкой на объект, не установленной для экземпляраошибка объекта.Что я делаю не так ... или, что более важно, как я могу протестировать этот простой методный модуль?

Stack Trace: на Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.CollectionReplacer.GetUnvalidatedCollections (контекст HttpContext) вMicrosoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.GetUnvalidatedCollections (контекст HttpContext, Func 1& formGetter, Func 1 & queryStringGetter) в System.Web.Helpers.Validation.Unvalidated (запрос HttpRequest). System.WtorF.F. 0 (ControllerContext cc) в System.Web.Mvc.FormValueProviderFactory.GetValueProvider (ControllerContext controllerContext) в System.Web.Mvc.ValueProviderFactoryCollection. <> C _DisplayClassc.ider_F..WhereSelectEnumerableIterator 2.MoveNext() at System.Linq.Enumerable.WhereSelectEnumerableIterator 2.MoveNext () в коллекции System.Collections.Generic.List 1..ctor(IEnumerable 1) в System.Linq.Enumerable.ToList [TSource] (источник IEnumerable`1) в System.Web.Mvc.ValueProviderFactoryCleclecletion.GetValueProvider (ControllerContext controllerContext) в System.Web.Mvc.ControllerBase.get_ValueProvider () в System.Web.Mvc.Controller.TryUpdateModel [TModel] (модель TModel) в Controllers.AdminController.ColateПроекты Visual Studio \ Controllers \ AdminController.cs: строка 254 в Tests.UnitTest1.TestAddStudy () в C: \ Проекты Visual Studio \ Tests \ UnitTest1.cs: строка 32

Ответы [ 2 ]

0 голосов
/ 09 декабря 2011

Глядя на трассировку стека, похоже, что исключение выдается при вызове TryUpdateModel(newStudy).Я могу только представить, что либо объект Study, который возвращается new Study(), не удовлетворяет требованиям TryUpdateModel(), либо существует некоторая зависимость, которая требуется ASP.NET MVC для того, чтобы этот метод работал, чтоотсутствует в контексте теста, но присутствует в контексте времени выполнения (при условии, что метод контроллера работает для вас при запуске функционального теста).

Если метод работает во время функционального теста, то последнее объяснение должно выполняться,Опять же, посмотрим на трассировку стека:context, Func1 & formGetter, Func1 & queryStringGetter) в System.Web.Helpers.Validation.Unvalidated (запрос HttpRequest) в

Похоже, что HttpRequest используется для выполнения некоторой проверки.Я полагаю, что вашему объекту фиктивного запроса необходимо установить некоторые дополнительные возвращаемые значения метода / свойства.В частности, я полагаю, что он должен по крайней мере возвращать NameValueCollection экземпляров из его свойств Form и QueryString, даже просто пустых.Разумно предположить, что код проверки в MVC предполагает, что эти свойства никогда не возвращают нулевые значения.Учитывая, что вы не установили возвращаемые значения для этих свойств в своих фиктивных объектах, это объяснило бы, почему NullReferenceException вбрасывается глубоко в код MVC.

Попробуйте добавить эти строки в свой код создания фиктивных объектов.: -

request.SetupGet(req => req.Form).Returns(new NameValueCollection());
request.SetupGet(req => req.QueryString).Returns(new NameValueCollection());

В зависимости от требований вашего теста и / или контроллера, вы можете обнаружить, что вам придется добавить некоторые значения как минимум в один из NameValueCollection экземпляров, чтобы более точновысмеивать содержание реального запроса.

0 голосов
/ 09 декабря 2011

Эта строка на самом деле возвращает объект или он нулевой?

Study currentStudy = ctx.Studies.Where(p => p.StudyID == id).FirstOrDefault();

Возможно, вы захотите проверить нулевое значение перед вызовом TryUpdateModel(currentStudy) следующим образом:

Study currentStudy = ctx.Studies.Where(p => p.StudyID == id).FirstOrDefault();
if (currentStudy != null) {
    TryUpdateModel(currentStudy);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...