Как стать автором
Обновить

ASP.NET MVC: модульное тестирование маршрутов

Время на прочтение4 мин
Количество просмотров4.4K
imageМодульное тестирование (unit test) очень важная часть современной разработки программного обеспечения. При тестировании web-приложений разработчики стараются охватить все аспекты работы приложения от получения запроса до выдачи результата. При разработке проектов с помощью ASP.NET MVC одним из таких моментов является механизм маршрутизации. Тестирование маршрутов обычно приносило немало головной боли, заставляя разработчика писать много сопутствующего кода. В этой заметке я покажу как используя пару инструментов можно упростить тестирование маршрутов до минимума.

Инструменты


Для начала нам понадобятся следующие инструменты:
  • MvcContrib – библиотека с дополнительным для ASP.NET MVC функционалом, в том числе в области модульного тестирования;
  • RhinoMocks – библиотека для создания фальшивых (mock) объектов упрощающих тестирование;
  • NUnit – среда модульного тестирования с набором собственных атрибутов и инструментов.

Установка


Установите NUnit, после этого добавьте в свой проект ссылки на сборки nunit.framework (из GAC), Rhino.Mocks и MvcContrib.TestHelper.

image

Среда готова для создания модульных тестов для маршрутов.

Тесты


Для того, чтобы показать примеры модульных тестов для маршрутов, давайте определим пару таких маршрутов:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
  "Product",
  "Product/{id}",
  new { controller = "Product", action = "GetById" }
);

routes.MapRoute("ProductList",
        "ProductList/{year}",
        new { controller = "Product", action = "List" },
        new { year = new YearConstraint() }
        );

routes.MapRoute(
  "Default",
  "{controller}/{action}/{id}",
  new { controller = "Home", action = "Index", id = "" }
);


* This source code was highlighted with Source Code Highlighter.

Обратите внимание на маршрут ProductList. Он содержит ограничение YearConstraint, код которого я пропущу, но скажу только, что это ограничение проверяет параметр year на принадлежность диапазону от 1900 до 2100.

Для тестирования создадим следующий класс:

namespace Routing
{
  using MvcContrib.TestHelper;
  using NUnit.Framework;
  using Routing.Controllers;
  using System.Web.Routing;
  using Rhino.Mocks;
  using System.Web;

  [TestFixture]
  public class TestRoutes
  {
    [TestFixtureSetUp]
    public void SetUp()
    {
      MvcApplication.RegisterRoutes(RouteTable.Routes);
    }
    [TestFixtureTearDown]
    public void TearDown()
    {
      RouteTable.Routes.Clear();
    }
  }
}


* This source code was highlighted with Source Code Highlighter.

Для тех, кто работал с NUnit ранее атрибуты будут знакомыми, остальным немножко расскажу про их назначение:
  • TestFixture – определяет класс с тестами;
  • TestFixtureSetUp – определяет метод с кодом, который нужно выполнить перед запуском тестов;
  • TestFixtureTearDown – определяет метод с кодом, который нужно выполнить после запуска тестов.
Как вы можете видеть, в классе создан метод, который инициализирует таблицу маршрутов перед тестированием и очищает ее после проведения тестов. Время написать первый тест:

[Test]
public void TestSimpleRoute()
{
  "~/".Route().ShouldMapTo<HomeController>(x => x.Index());
}


* This source code was highlighted with Source Code Highlighter.

Здесь, с использованием методов расширения библиотеки MvcContrib мы проверяем на работоспособность запрос к корню проекта, который согласно определенным нами маршрутам, должен маршрутизироваться с помощью маршрута Default. Этот маршрут создается в ASP.NET MVC-приложениях по умолчанию. Запрос к корню проекта по умолчанию должен маршрутизироваться в выполнение действия Index контроллера HomeController.

Скомпилируем проект и запустим NUnit. Выбрав в качестве проекта нашу сборку с тестом нажмем Run для запуска теста. Результат на картинке ниже:

image

Тест пройден. Добавим остальные тесты:

[Test]
public void TestProduct()
{
  "~/Product/750".Route().ShouldMapTo<ProductController>(x => x.GetById(750));
}
[Test]
public void TestProductListValidYear()
{
  "~/ProductList/2009".Route().ShouldMapTo<ProductController>(x => x.List(2009));
}
[Test]
public void TestProductListInvalidYear()
{
  Assert.AreNotEqual("~/ProductList/1800".Route().Values["controller"], "Product");
}
[Test]
public void TestIgnoreAxd()
{
  "~/someroutetoigonre.axd".ShouldBeIgnored();
}


* This source code was highlighted with Source Code Highlighter.

Здесь представлено четыре теста:
  • TestProduct – предназначен для тестирования маршрута Product;
  • TestProductListValidYear – тест для тестирования маршрута с ограничением при правильно заданном параметре year;
  • TestProductListInvalidYear — тест для тестирования маршрута с ограничением при неправильно заданном параметре year;
  • TestIgnoreAxd – тест для тестирования маршрута игнорирования запросов к axd-ресурсам.
Обратите внимание на TestProductListInvalidYear. В этом тесте мы проверяем работу маршрутизации при попытке обратиться к маршруту PriductList с неверным параметром. Проверка несколько косвенная: мы убеждаемся что при неверном параметре механизм маршрутизации не вызовет контроллер Product.

И последнее на что стоит обратить внимание – это то, как легко создается тест для проверки маршрутов игнорирования. Метод расширения ShouldBeIgnored позволяет задать тест для таких маршрутов. В нашем тесте TestIgnoreAxd мы пытаемся представить ситуацию с обращением к некоему axd-ресурсу, которое, согласно заданным маршрутам должно игнорироваться.

Скомпилируем и запустим тесты в NUnit:

image

Все тесты пройдены. Работа сделана.

Заключение


В этой статье я рассмотрел простейшие варианты тестов для модульного тестирования маршрутов в ASP.NET MVC. Инструменты, которые представлены в библиотеке MvcContrib позволяют очень просто создавать такие тесты и, безусловно, облегчают жизнь разработчику.

Для своих проектов, вероятно, вы захотите создать более подробные модульные тесты работы механизма маршрутизации. В этом вам поможет MvcContrib. Программируйте с удовольствием!

Progg it
Теги:
Хабы:
+14
Комментарии6

Публикации

Изменить настройки темы

Истории

Работа

.NET разработчик
68 вакансий

Ближайшие события

PG Bootcamp 2024
Дата16 апреля
Время09:30 – 21:00
Место
МинскОнлайн
EvaConf 2024
Дата16 апреля
Время11:00 – 16:00
Место
МоскваОнлайн
Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн