in ASP.NET

Testando rotas com o MVC Route/URL Generation Unit Tester

O ASP.NET MVC é um framework de desenvolvimento web extremamente poderoso, extensível e testável. Com diversas técnicas, é possível testar cada parte de nossas aplicações.

O roteamento (Routing) do ASP.NET MVC é uma das partes mais criticas de nossas aplicações, é nela que criamos as estruturas que definirão para quais actions, controlles e quais parâmetros serão acionados de acordo com as urls das requisições que chegam em nossas aplicações.

O MVC Route/URL Generation Unit Tester é um projeto que torna extremamente fácil e simples testar os rotas de uma aplicação ASP.NET MVC.

Instalando

Esta biblioteca é distribuída via Nuget. Lembrando de instalar sempre no projeto de testes da nossa solution, e não no projeto web.

PM> Install-Package MvcRouteUnitTester

 

Testando

Criei uma aplicação de testes que tem algumas rotas especificas:

Url: “/sobre”

Controller: “Acessorio”

Action=”Sobre”

 

Url: “/{tipo}/classificados” ex:( /esportivos/classificados, /utilitarios/classificados)

Controller: “Carro”

Action: “Lista“

Parâmetros: tipo=”tipo do carro”

 

 

Url: “/{tipo}/{carro}” ex:( /compactos/celta, /utilitarios/kombi)

Controller: “Carro”

Action: “Detalhe“

Parâmetros: tipo=”tipo do carro”, carro=”nome do carro”

 

 

Url: “/{Controller}/{Action}/{Id}” ex:( /, /Home/About, /Home/Index)

Controller: “Controller”

Action: “Action“

Parâmetros: id

 

Para isso, deixei o método RegisterRoutes da seguinte maneira (rotas configuradas da mais especifica para a mas genérica):

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "RotaSobre", // Route name
        "sobre", // URL with parameters
        new { controller = "Acessorio", action = "Sobre"} // Parameter defaults
    );

    routes.MapRoute(
        "RotaTipoDeCarro", // Route name
        "{tipo}/classificados", // URL with parameters
        new { controller = "Carro", action = "Lista" } // Parameter defaults
    );

    routes.MapRoute(
        "RotaCarro", // Route name
        "{tipo}/{carro}", // URL with parameters
        new { controller = "Carro", action = "Detalhe" } // Parameter defaults
    );

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );

}

 

Agora, vou adicionar um projeto de testes na minha solution:

image

 

Nesse projeto de testes eu vou adicionar o MVC Route/URL Generation Unit Tester, para isso vou utilizar o Packager Manager Console: “Install-Package MvcRouteUnitTester”

image

 

Com isso, podemos começar a testar nossas rotas Alegre. Basicamente podemos testar os vários tipos de uso da tabela de roteamento, podemos testar as requisições que são feitas para a nossa aplicação (Incoming Routes), podemos testar como está sendo feita as urls que estão sendo geradas através da tabela de rotamento(Outgoing Routes) com helpers como @Url.Action(“Action”,”Controller”).

Para conseguir testar as rotas eu precisei referenciar o projeto web no meu projeto de testes, e referenciar também o System.Web:

image

Incoming Routes

 

Para este exemplo, no projeto de testes, eu criei um classe chamada RouteTest, e nela um teste chamado IncommingRoutes, que será responsável por testar as rotas das requisições que chegam. Claro que em um projeto de produção, o ideal é criar métodos e testes para cada tipo e agrupamento de rota, e não deixa elas em um único teste.

namespace UnitTestProject1
{
    [TestClass]
    public class RouteTest
    {
        [TestMethod]
        public void IncomingRoutes()
        {

        }
    }
}

O primeiro objeto que eu devo instanciar em um teste é o RouteTest, passando a classe da minha aplicação web

var tester = new RouteTester<MvcApplication>();

 

Com o objeto tester é possível chamar um método chamado WithIncomingRequest, que recebe como parâmetro a url da requisição e o verbo Http (GET como padrão).

image

E após ele, o método ShouldMatchRoute, com os parâmetros de Controlle e Action.

image

Com esses métodos eu testei algumas variações das urls da aplicação, deixando o método de teste da seguinte maneira:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcApplication4;
using MvcRouteUnitTester;

namespace UnitTestProject1
{
    [TestClass]
    public class RouteTest
    {
        [TestMethod]
        public void IncomingRoutes()
        {
            var tester = new RouteTester<MvcApplication>();

            tester.WithIncomingRequest("/sobre")
                .ShouldMatchRoute("Acessorio", "sobre");

            tester.WithIncomingRequest("/compactos/classificados")
                .ShouldMatchRoute("Carro", "Lista", new { tipo = "compactos" });
            tester.WithIncomingRequest("/esportivos/classificados")
                .ShouldMatchRoute("Carro", "Lista", new { tipo = "esportivos" });

            tester.WithIncomingRequest("/esportivos/mustang")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "esportivos", carro="mustang" });
            tester.WithIncomingRequest("/compactos/celta")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "compactos", carro = "celta" });
            tester.WithIncomingRequest("/utilitarios/kombi")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "utilitarios", carro = "kombi" });

            tester.WithIncomingRequest("/")
                .ShouldMatchRoute("Home", "Index");
            tester.WithIncomingRequest("/Home")
                .ShouldMatchRoute("Home", "Index");
        }
    }
}

Com isso, agora ao executarmos os testes veremos que eles passarão com sucesso.

image

Agora, caso alguém faça alguma manutenção no registro das rotas, e por engano altere a ordem (como no exemplo), ou faça alguma alteração que quebre alguma rota, é só executar novamente os testes e ter a certeza que o roteamento de nossa aplicação está funcionando.

No exemplo abaixo eu alterei a ordem em que as rotas eram registradas.

image

Com isso, ao executar nossos testes, veremos que a url de classificados deixou de funcionar corretamente, de acordo com o que foi escrito no teste:

image

Debugando o teste é possível ver o detalhe do erro

image

 

Outgoing Routes

Outro tipo de teste importante para realizamos em nossas aplicações é o das Outgoing Routes, é o tipo de teste que garante de as urls que estão sendo criadas através dos helpers, ou redirectes estão funcionando corretamente.

Neste teste eu basicamente passo o Controller, Action e parâmetros, e testo como a url foi gerada.

Como no outro teste eu preciso instanciar um objeto do tipo RouteTester:

var tester = new RouteTester<MvcApplication>();

Utilizo o método WithRouteInfo, passando os valores de Controller e Action, e testo com o método ShouldGenerateUrl.

[TestMethod]
public void OutgoingRoutesTest()
{
    var tester = new RouteTester<MvcApplication>();

    tester.WithRouteInfo("Acessorio","Sobre").ShouldGenerateUrl("/sobre");
}

 

image

image

 

Com ele é possível garantir os padrões das urls que são geradas por nossa aplicação.

Aqui está o exemplo de como ficou a classe com nossos testes.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcApplication4;
using MvcRouteUnitTester;

namespace UnitTestProject1
{
    [TestClass]
    public class RouteTest
    {
        [TestMethod]
        public void IncomingRoutes()
        {
            var tester = new RouteTester<MvcApplication>();

            tester.WithIncomingRequest("/sobre")
                .ShouldMatchRoute("Acessorio", "sobre");

            tester.WithIncomingRequest("/compactos/classificados")
                .ShouldMatchRoute("Carro", "Lista", new { tipo = "compactos" });
            tester.WithIncomingRequest("/esportivos/classificados")
                .ShouldMatchRoute("Carro", "Lista", new { tipo = "esportivos" });

            tester.WithIncomingRequest("/esportivos/mustang")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "esportivos", carro = "mustang" });
            tester.WithIncomingRequest("/compactos/celta")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "compactos", carro = "celta" });
            tester.WithIncomingRequest("/utilitarios/kombi")
                .ShouldMatchRoute("Carro", "Detalhe", new { tipo = "utilitarios", carro = "kombi" });

            tester.WithIncomingRequest("/")
                .ShouldMatchRoute("Home", "Index");
            tester.WithIncomingRequest("/Home")
                .ShouldMatchRoute("Home", "Index");
        }

        [TestMethod]
        public void OutgoingRoutesTest()
        {
            var tester = new RouteTester<MvcApplication>();

            tester.WithRouteInfo("Acessorio", "Sobre").ShouldGenerateUrl("/sobre");

            tester.WithRouteInfo("Carro", "Lista", new { tipo = "compactos" })
                .ShouldGenerateUrl("/compactos/classificados");
            tester.WithRouteInfo("Carro", "Lista", new { tipo = "esportivos" })
                .ShouldGenerateUrl("/esportivos/classificados");
        }
    }
}

 

Assim, com o MVC Route/URL Generation Unit Tester, podemos garantir, e testar o roteamento de nossas aplicações Alegre

 

Espero que este post seja útil,

estou a disposição para dúvidas, criticas ou sugestões

abs

Rodolfo

  • Anonymous

    Muito bom, Rodolfo! Bem mais simples e prático dessa maneira (acho que eu que tava de bobeira do jeito errado)

    Ah, fazia tempo que eu não entrava no sue blog, tá bonito :*

  • http://tecnologia.minhavida.com.br/2013/02/testando-rotas-com-o-mvc-routeurl-generation-unit-tester/ Testando rotas com o MVC Route/URL Generation Unit Tester | Blog de Tecnologia do Minha Vida

    […] (post original) This entry was posted in ASP.NET, Desenvolvimento and tagged ASP.NET, MVC, ROUTE by Rodolfo Fadino. Bookmark the permalink. /* […]