Книга: ASP.NET MVC Framework

Создание тестов

Создание тестов

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

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 = "" }

Как вы можете видеть, в коде определяется три маршрута: Product, ProductList и маршрут по умолчанию Default. Кроме того, определено стандартное правило игнорирования маршрута для игнорирования запросов к

AXD-ресурсам. Обратите внимание, что маршрут с названием ProductList содержит ограничение для параметра year (ранее в этой главе мы рассматривали это ограничение).

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

namespace Routing {
  using System.Web.Routing;
  using MvcContrib.TestHelper;
  using NUnit.Framework;
  using Routing.Controllers;
  [TestFixture]
  public class TestRoutes
  {
  }
}

Обратите внимание на использование атрибута TestFixture. Это атрибут инструмента NUnit, который позволяет определить класс с набором тестов. Добавим в класс простой тест:

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

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

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

C помощью пункта меню File | Open Project добавим в среду сборку нашего проекта тестирования. В моем случае это сборка Routing.dll. После того как сборка загрузится, нажмите кнопку Run для запуска тестов. Как можно убедиться, наш тест не пройден (рис. 6.8).

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



маршрутизации и создает маршруты, необходимые для последующего тестирования:

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

Обратите внимание на атрибуты TestFixtureSetUp и TestFixtureTearDown. Эти атрибуты необходимы для определения кода, который будет вызван перед тестом и сразу после него. В нашем случае перед тестами создаются маршруты, а после теста — разрушаются.

Скомпилируем проект и запустим тест еще раз. На этот раз тест пройден (рис. 6.9).


Для интереса вы можете теперь попробовать модифицировать маршрут Default так, чтобы наш тест перестал работать, например, можно переименовать название действия по умолчанию с Index на Index2. После этого тест будет провален.

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

[Test]
public void TestProduct()
{
  "~/Product/750".Route()
         .ShouldMapTo<ProductController>(x => x.GetById(750));
}

Добавим еще один тест, на этот раз для проверки игнорирования маршрута для AXD-запросов:

[Test]
public void TestIgnoreAxd()
{
  "~/someroutetoigonre.axd".ShouldBeIgnored();
}

Запустите тесты и убедитесь, что они пройдены. Обратите внимание на используемый метод расширения ShouldBeIgnored, который предназначен как раз для тестирования игнорирования маршрутов.

Последний наш тест будет направлен на проверку ограничений маршрута. Для тестирования маршрута ProductList определим два следующих теста:

[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");
}

Первый тест TestProductListValidYear производит знакомые нам действия, при правильном значении параметра year, ограничение не должно действовать и маршрут должен быть сопоставлен контроллеру Product и действию List. Второй тест TestProductListInvalidYear, наоборот, проверяет поведение маршрута при неверном с точки зрения ограничения параметре year (он должен быть более или равен 1900). Для того чтобы протестировать этот момент, сравниваются имя сопоставленного контроллера и имя контроллера Product. Для успешного прохождения теста они не должны быть равны. Теперь, если убрать ограничение из маршрута, тест будет провален.

После написания всех тестов и запуска NUnit мы должны получить следующую картину успешного прохождения всех тестов (рис. 6.10).


В листинге 6.3 приведен код перечисленных ранее тестов для тех, кто использует тестирование на базе встроенного в Visual Studio инструмента MSTest. Различий минимум и все они касаются именования атрибутов, которое в NUnit отличается от MSTest.

Листинг 6.3. Тестирование с помощью MSTest

namespace Routing
{
  using System.Web.Routing;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using MvcContrib.TestHelper; using Routing.Controllers;
  [TestClass]
  public class TestRoutesMSTest
  {
    [TestMethod]
    public void TestSimpleRoute()
    {
      "~/".Route().ShouldMapTo<HomeController>(x => x.Index());
    }
    [TestInitialize]
    public void SetUp()
    {
      MvcApplication.RegisterRoutes(RouteTable.Routes);
    }
    [TestCleanup]
    public void TearDown()
    {
      RouteTable.Routes.Clear();
    }
    [TestMethod]
    public void TestProduct()
    {
      "~/Product/750".Route()
           .ShouldMapTo<ProductController>(x => x.GetById(750));
    }
    [TestMethod]
    public void TestIgnoreAxd()
    {
      "~/someroutetoigonre.axd".ShouldBeIgnored();
    }
    [TestMethod]
    public void TestProductListValidYear()
    {
      "~/ProductList/2009".Route()
             .ShouldMapTo<ProductController>(x => x.List(2009));
    [TestMethod]
    public void TestProductListInvalidYear()
    {
      Assert.AreNotEqual("~/ProductList/1800".Route()
                  .Values["controller"], "Product");
    }
  }
}

Оглавление книги


Генерация: 0.580. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз