Тестирование маршрутов в asp.net MVC - PullRequest
0 голосов
/ 07 января 2011

Я использую код из книги Steve Sandersons MVC Framework (2-е изд.). У меня есть класс под названием Category, который создает RouteValueDictionary, используя его другие свойства, которые я затем использую в меню. На сайте все работает нормально, маршрутизация правильная и ссылки выводятся в порядке исключения. Тем не менее, я пытаюсь создать для них тест. Вот мой класс Категория:

public class Category
{
    public Category()
    {
    }   
    public Category(int id, string title, int sortOrder, int? parentId, bool isMainCategory, bool isVisible)
    {
        Id = id;
        Title = title ?? "Home";
        SortOrder = sortOrder;
        ParentId = parentId;
        IsMainCategory = isMainCategory;
        IsVisible = isVisible;
    }

    private RouteValueDictionary routeValues;

    public int Id { get; set; }
    public string Title { get; set; }
    public int? ParentId { get; set; }
    public bool IsMainCategory { get; set; }
    public bool IsVisible { get; set; }
    public int SortOrder { get; set; }

    public List<Category> SubCategories { get; set; }

    public RouteValueDictionary RouteValues {
        get
        {
            if (routeValues == null)
            {
                routeValues = new RouteValueDictionary(new
                {
                    controller = "Products",
                    action = "Index",
                    cat = Id,
                    categoryName = UrlWorker.CleanUrl(Title)
                    //,
                    //page = 1,
                    //isParent = parent
                });
            } 
            return routeValues;
        }
        set
        {
            routeValues = value;

        }
    }
}

Вот тест, который я настроил:

[TestMethod]
    public void CategoryGoesToCorrectRoute()
    {
        List<Category> list = categoryService.GetVisibleCategories();
        Assert.AreEqual("/products/3/category-3", GenerateUrlViaMocks(new RouteValueDictionary(new
        {
            controller = "products",
            action = "Index",
            cat = 3,
            categoryName = "category-3"
        })));

        //list[0].RouteValues));
    }

И метод GenerateUrlViaMocks:

    private string GenerateUrlViaMocks(object values)
    {
        // Arrange (get the routing config and test context)
        RouteCollection routeConfig = new RouteCollection();
        RegisterAllAreas(routeConfig);
        MvcApplication.RegisterRoutes(routeConfig);
        var mockContext = MakeMockHttpContext(null);

        RouteData routeData = routeConfig.GetRouteData(mockContext.Object);

        RequestContext context = new RequestContext(mockContext.Object, routeData);
        // Act (generate a URL)
        return UrlHelper.GenerateUrl(null, null, null,
        new RouteValueDictionary(values), routeConfig, context, true);
    }

Наконец, вот моя таблица маршрутизации:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.MapRoute(
            "SizeGuide",
            "products/sizing",
            new { controller = "products", action = "Sizing" },
            new string[] { "EliteFightKit.Web.Controllers" }
        );
        routes.MapRoute(
            "ViewCategory",
            "products/{cat}/{categoryName}",
            new { controller = "products", action = "Index", cat = 0, categoryName = "" },
            new string[] { "EliteFightKit.Web.Controllers" }
        );

        routes.MapRoute(
            "ViewProduct",
            "products/{cat}/{id}/{productName}",
            new { controller = "products", action = "Details", cat = "", id = "", productName = "" },
            new string[] { "EliteFightKit.Web.Controllers" }
        );

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

        routes.MapRoute(
            "Sitemap",
            "sitemap",
            new { controller = "Sitemap", action = "Index" }
        );
        routes.MapRoute(
            "Default", 
            "{controller}/{action}/{id}",
            new { action = "Index", id = "" },
            new string[] { "EliteFightKit.Web.Controllers" }
        );
        routes.MapRoute(
            "Root",
            "",
            new { controller = "Home", action = "Index", id = "" }
        );
    }

Проблема, с которой я столкнулся, заключается в том, что фактический результат теста возвращается как /products/sizing?Count=4...

... это набор "кодов" в кодировке URL, который в основном обозначает словарь (извините, я не могу распечатать фактическую ошибку в тот момент, когда я нахожусь за пределами машины, которая позволяет мне запускать тесты ). Учитывая, что это работает на веб-сайте, я думаю, что это проблема с тем, как я настраиваюсь в GenerateUrlViaMocks. Параметры routeValues, передаваемые в этот метод, являются правильными, поэтому я действительно смущен, почему он не улавливает тот факт, что в моих параметрах маршрута есть параметры «cat» и «categoryName». Куда я иду не так?

Lloyd

Ответы [ 2 ]

2 голосов
/ 10 января 2011

Я обнаружил, что проблема была в этой строке:

return UrlHelper.GenerateUrl(null, null, null,
        new RouteValueDictionary(values), routeConfig, context, true);

Значения, которые уже были RouteValueDictionary, были преобразованы в другой RouteValueDictionary.Таким образом, все свойства, такие как Count, Keys, Values ​​были помещены в значения Key в следующем RVD.

Я изменил его на следующее:

return UrlHelper.GenerateUrl(null, null, null, 
            (RouteValueDictionary)values, routeConfig, context, true);

, и это работает:)

0 голосов
/ 07 января 2011

Ну, вы не указываете имя маршрута, поэтому "SizeGuide", который не имеет полезного ограничения, но имеет значения по умолчанию, сопоставляется. Это, вероятно, неправильно. Вам необходимо либо указать имя маршрута при вызове GenerateUrl, либо добавить ограничения к маршруту.

...