Я пытаюсь запустить простой тест на контроллере в 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, но, по крайней мере, это обходной путь.