Pull to refresh

Unit тестирование в ASP.NET MVC Framework-е

Reading time 4 min
Views 2.1K
В свое время делая доклад по ASP.NET MVC Framework я заметил, что данный framework дает возможность разработчиком использовать TDD практики при разработки и тут же получил вопрос, что такое TDD, почему и как именно ASP.NET MVC Framework дает эти самые возможности.


ASP.NET MVC Framework + TDD


Самый первый намек на TDD разработчик получает как только пытается создать проект, используя шаблон «ASP.NET MVC Web application». Тут же будет предложено создать еще один проект, под тесты.

В данном случае предложено воспользоваться стандартными технологиями тестирования MS, но в инете есть решения как добавить и xUnit, и MbUnit, и nUnit. Если воспользоваться таким намеком, то получим еще один проект в котором будут подключены все необходимые библиотеки для тестирования, будет создан cs-файл с одним классом и методом, дальше уже придется делать все ручками.

Начиная с Preview 2, все Action методы, должны возвращать результат. Результатом может быть любой класс наследованный от базового типа ActionResult(ViewResult, JsonResult, ActionRedirectResult и так далее). Таким образом при тестировании можно легко проверить данные которые передает ваш метод для View(ViewData).
ViewResult data = blogController.Comments(5);
Assert.AreEqual(expect, data.ViewData.Model);

* This source code was highlighted with Source Code Highlighter.

Помимо этого если метод возвращает ViewResult, можно так же легко проверить какой именно View будет использован.
ViewResult data = blogController.Comments(5);
Assert.AreEqual("comments", data.ViewName);


* This source code was highlighted with Source Code Highlighter.


Так же в самом framework-е нету ни одного sealed класса, а все типы построены на интерфейсах(IView, IController) или имеют свой базовый абстрактный класс(HttpResponseBase, HttpSessionStateBase). Такой подход легко позволит мокнуть какой-либо класс при тестировании. Что, например, позволит протестировать маршруты.

  var httpContextMock = new Mock<HttpContextBase>();
  var requestMock = new Mock<HttpRequestBase>();
  httpContextMock.Expect(c => c.Request).Returns(requestMock.Object);
  requestMock.Expect(r => r.AppRelativeCurrentExecutionFilePath)
    .Returns(url);

  RouteData routeData = routes.GetRouteData(httpContextMock.Object);
  Assert.IsNotNull(routeData, "Should have found the route");


* This source code was highlighted with Source Code Highlighter.


Так что MS избрав для данной технологии TDD подход, вынужденны использовать те решения, которые позволят конечным пользователям легко следовать их примеру.

Так в RC1 появилась возможность автоматически создавать View для нужного Action Method, почему бы не пойти дальше и не встроить возможность автоматического создания набора тестов(Конечно все test case покрыть не возможно, но наиболее повторяющиеся… Почему бы и нет.)

Ну под конец один тест для моего метода и как это выглядит в nUnit-e.

Небольшой пример теста и метода.

  1.   [TestFixture]
  2.   public class TestCase4BlogsController
  3.   {
  4.     
  5.     [Test]
  6.     public void TestGetCommentsList_IfPutIDExistBlog()
  7.     {
  8.       MockModel mockModel = new MockModel();
  9.       BlogController blogController = new BlogController();
  10.       ArrayList expect = new ArrayList {new { Data = "Это вам не рыбу, динамитом глушить", Date = "12.02.2009", Author = "Иван Петрович"},
  11.                         new { Data = "Дык динамитом, оно эффективнее", Date = "13.02.2009", Author = "Пацак"},
  12.                         new { Data = "И что ты потом будешь делать с этой рыбой ???", Date = "13.02.2009", Author = "Иван Петрович"} };
  13.  
  14.  
  15.       mockModel.comments = expect;
  16.       blogController.Model = mockModel as IBlogModel;
  17.  
  18.  
  19.       ViewResult data = blogController.Comments(5);
  20.       Assert.AreEqual(expect, data.ViewData.Model);
  21.     }
  22.  
  23.   }
* This source code was highlighted with Source Code Highlighter.


  1.   public class MockModel : IBlogModel
  2.   {
  3.     public ArrayList comments = null;
  4.  
  5.     #region IBlogModel Members
  6.  
  7.     public ArrayList GetComment4Blog(int blogId)
  8.     {
  9.       return comments;
  10.     }
  11.  
  12.     #endregion
  13.   }
* This source code was highlighted with Source Code Highlighter.


До того как метод был написан.


Реализация метода.
  1.     [AcceptVerbs(HttpVerbs.Get)]
  2.     public ViewResult Comments(int blogId)
  3.     {
  4.       return View("comments", Model.GetComment4Blog(blogId));
  5.     }
* This source code was highlighted with Source Code Highlighter.


После компиляции.


Tags:
Hubs:
+1
Comments 0
Comments Leave a comment

Articles