Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Проверка авторизации
Например, мы должны проверить, что, если я захожу не под админом, то в авторизованную часть (в контроллер, помеченный атрибутом [Authorize(Roles=“admin”)]) – обычному польвателю не дадут войти. Есть отличный способ это проверить. Обратим внимание на класс ControllerActionInvoker и отнаследуем его для вызовов (/Fake/FakeControllerActionInvoker.cs + FakeValueProvider.cs): public class FakeValueProvider { protected Dictionary< string, object> Values { get; set; }
public FakeValueProvider() { Values = new Dictionary< string, object> (); }
public object this[string index] { get { if (Values.ContainsKey(index)) { return Values[index]; } return null; }
set { if (Values.ContainsKey(index)) { Values[index] = value; } else { Values.Add(index, value); } } } } public class FakeControllerActionInvoker< TExpectedResult>: ControllerActionInvoker where TExpectedResult: ActionResult { protected FakeValueProvider FakeValueProvider { get; set; }
public FakeControllerActionInvoker() { FakeValueProvider = new FakeValueProvider(); }
public FakeControllerActionInvoker(FakeValueProvider fakeValueProvider) { FakeValueProvider = fakeValueProvider; }
protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList< IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary< string, object> parameters) { return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters); }
protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { var obj = FakeValueProvider[parameterDescriptor.ParameterName]; if (obj! = null) { return obj; } return parameterDescriptor.DefaultValue; }
protected override void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) { Assert.IsInstanceOf< TExpectedResult> (actionResult); } } По сути это «вызывальщик» action-методов контроллеров, где Generic класс – это ожидаемый класс результата. В случае неавторизации это будет HttpUnauthorizedResult. Сделаем тест (/Test/Admin/HomeControllerTest.cs): [TestFixture] public class AdminHomeControllerTest { [Test] public void Index_NotAuthorizeGetDefaultView_RedirectToLoginPage() { var auth = DependencyResolver.Current.GetService< IAuthentication> (); auth.Login(" chernikov@gmail.com", " password2", false);
var httpContext = new MockHttpContext(auth).Object; var controller = DependencyResolver.Current.GetService< Areas.Admin.Controllers.HomeController> (); var route = new RouteData(); route.Values.Add(" controller", " Home"); route.Values.Add(" action", " Index"); route.Values.Add(" area", " Admin");
ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller); controller.ControllerContext = context;
var controllerActionInvoker = new FakeControllerActionInvoker< HttpUnauthorizedResult > (); var result = controllerActionInvoker.InvokeAction(controller.ControllerContext, " Index"); }
} Запускаем тест, он проходит. Сделаем, чтобы авторизация была под пользователем admin и будем ожидать получение ViewResult: [Test] public void Index_AdminAuthorize_GetViewResult() { var auth = DependencyResolver.Current.GetService< IAuthentication> (); auth.Login(" admin", " password", false);
var httpContext = new MockHttpContext(auth).Object; var controller = DependencyResolver.Current.GetService< Areas.Admin.Controllers.HomeController> (); var route = new RouteData(); route.Values.Add(" controller", " Home"); route.Values.Add(" action", " Index"); route.Values.Add(" area", " Admin");
ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller); controller.ControllerContext = context;
var controllerActionInvoker = new FakeControllerActionInvoker< ViewResult> (); var result = controllerActionInvoker.InvokeAction(controller.ControllerContext, " Index"); } Так же прошли. Молодцом. На этом давайте остановимся и подумаем, чего мы достигли. Мы можем оттестировать любой контроллер, проверить правильность любой валидации, проверку прав пользователя. Но это касается только контроллера. А как же работа с моделью? Да, мы можем проверить, что вызывается метод репозитория, но на этом всё. Да, мы можем написать Mock-методы для добавления, изменения, удаления, но как это поможет решить ту проблему, о которой я писал вначале главы? Как мы заметим, что что-то не так при упущении поля с тегом? В хрестоматийном примере NerdDinner тесты не покрывают эту область. Есть IRepository, есть SqlRepository, есть MockRepository. И всё что находится в SqlRepository – это не покрытая тестами область. А там может быть реализовано очень многое. Что же делать? К чему этот TDD?
|