xVal вызывает сбой NUnit при проверке ModelState.IsValid

Я пытаюсь запустить простой тест на контроллере в MVC. Этот контроллер проверяет ввод с помощью xVal и DataAnnotations. Когда я запускаю тест (используя NUnit через Resharper, NUnit standalone или TestDriven.Net), он вызывает сбой бегуна без достойного сообщения об ошибке. В журналах событий есть довольно типичное сообщение об ошибках .NET Runtime 2.0, в котором говорится, что исполнитель был приложением с ошибкой.

Ошибка вызвана вызовом ModelState.IsValid (я знаю это, потому что, когда я вынимаю его, он работает нормально). Кроме того, сбой происходит только тогда, когда я запускаю тест в обычном режиме. Когда я запускаю тест в режиме отладки, он работает нормально.

Когда я удаляю ссылки на xVal и устанавливаю ошибку в состоянии модели с помощью ModelState.AddModelError, сбой не происходит.

Ниже представлен тестируемый контроллер и тестовый класс. Вы видите здесь что-нибудь не так?

Контроллер в стадии тестирования

using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using xVal.ServerSide;

namespace TestModelState.Controllers
{
    public class ThingController : Controller
    {
        [HttpPost]
        public ActionResult Create(Thing thing)
        {
            try
            {
                var errors = DataAnnotationsValidationRunner.GetErrors(thing);
                if (errors.Any())
                {
                    throw new RulesException(errors);
                }
            }
            catch (RulesException ex)
            {
                ex.AddModelStateErrors(ModelState, "thing");
            }
            if (ModelState.IsValid)
            {
                // Do some save stuff here
                return RedirectToAction("Index");
            }
            else
            {
                return View();
            }
        }
    }

    public class Thing
    {
        [Required]
        public string Name { get; set; }
    }

    internal static class DataAnnotationsValidationRunner
    {
        public static IEnumerable<ErrorInfo> GetErrors(object instance)
        {
            return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
                   from attribute in prop.Attributes.OfType<ValidationAttribute>()
                   where !attribute.IsValid(prop.GetValue(instance))
                   select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(string.Empty), instance);
        }
    }
}

Тестовый класс

using System.Web.Mvc;
using NUnit.Framework;
using TestModelState.Controllers;

namespace TestModelState.Tests
{
    [TestFixture]
    public class ThingControllerTests
    {
        [Test]
        public void Create_InvalidThing_SetsModelState()
        {
            // Arrange
            var thingController = new ThingController();
            var thing = new Thing();

            // Act
            var result = thingController.Create(thing);

            // Assert
            var viewResult = (ViewResult)result;
            Assert.IsFalse(viewResult.ViewData.ModelState.IsValid);
        }
    }
}

Версии - ASP.Net MVC - 2.0.0.0, NUnit - 2.5.3.9345, xVal - 1.0.0.0

Обновление. Когда я использую вместо этого следующий оператор (это то, что ModelState.IsValid скрыто делает), сбой не происходит ...

var modelStateIsValid = ModelState.Values.All(ms => ms.Errors.Count == 0);

Я бы по-прежнему предпочел использовать ModelState.IsValid, но, по крайней мере, это обходной путь.


person Russell Giddings    schedule 18.02.2010    source источник
comment
То же самое и со мной. это странно !!.   -  person Wahid Bitar    schedule 08.03.2010


Ответы (1)


ModelState.IsValid устанавливается не контроллером, а структурой привязки модели. Привязка модели - framework запускается только при обработке входящих HTTP-запросов. Когда вы вызываете действия контроллера явно, как указано выше, привязка модели не происходит, и, следовательно, весь ModelState находится в неопределенном состоянии. у тебя есть несколько способов

  1. Имитируйте весь материал привязки модели в своих тестах, как указано в этом вопросе SO - Как я могу протестировать ModelState?

  2. Вы можете использовать метод TryUpdateModel в действии вашего контроллера, как указано в этом вопросе SO - Модульные тесты для проверки MVC < / а>

  3. Напишите отдельные модульные тесты, которые проверяют валидацию ваших моделей на основе атрибутов. Для этого вам нужно будет изменить свой подход к проверке на основе атрибутов. Подробнее читайте в этой статье - http://jesschadwick.blogspot.com/2009/04/cleaner-validation-with-aspnet-mvc.html

person Community    schedule 05.10.2011