Vinicius Quaiato

{tecnologia, conceitos, negócios, idéias, práticas, .NET, ruby, osx, ios e algo mais}

Testando controllers que retornam Json


Fala galera. Mostrei por alto um teste de controller ASP.NET MVC que retornava Json aqui neste post. A idéia agora é trabalhar um pouco mais este tipo de teste e deixar claro o que podemos fazer com isso.

Quando estamos trabalhando com actions que retornam Json o problema que temos é que elas não retornam Json!
O JsonResult retornado possui um método ExecuteResult, e é este o método responsável por gerar o Json e colocar no response. Se quisermos testar efetivamente o Json precisamos executar este método, ou de alguma maneira fazer o que ele faz.Vamos utilizar o seguinte Controller como exemplo:

public class HomeController : Controller{    

public JsonResult DadosJson()    {        return Json(new { Id = 10, Nome = "Vinicius" }
);
    }
}

Bastante simples. Estamos apenas retornando 2 valores a serem transformados em Json.Vamos ao nosso teste:

[TestMethod]
public void TestMethod1(){
var controller = new HomeController();
var result = controller.DadosJson();
    Assert.AreEqual(@"{
"Id"":10,""Nome"":""Vinicius""}
", result.Data);
    }

Isso é o que eu queria fazer, mas infelizmente não é possível.

JavaScriptSerializer

Uma das alternativas, a mais simples ao meu ver, é adicionar estas duas linhas de código ao teste:

[TestMethod]
public void TestMethod1(){
var controller = new HomeController();
var result = controller.DadosJson();
var serializer = new JavaScriptSerializer();
var output = serializer.Serialize(result.Data);
    Assert.AreEqual(@"{
"Id"":10,""Nome"":""Vinicius""}
", output);
    }

Com o código das linhas 7 e 8 serializamos os nossos dados em forma Json, e podemos utilizá-los em nosso teste para a verificação.Eu achei que houvesse um problema com esse código. Em um primeiro momento pode parecer que este não é exatamente o código que o ASP.NET MVC executa, então pode parecer um pouco falho. no entanto, se formos olhar o código fonte do ASP.NET MVC no CodePlex veremos que é basicamente isso mesmo que ele faz:http://aspnet.codeplex.com/SourceControl/changeset/view/55373#266491Desta forma fica bem claro que ao menos por enquanto este código pode ser utilizado com segurança para testar actions que retornam dados em formato Json.Podemos melhorar um pouco isso, e criar um extension method para o JsonResult e utilizar em nossos testes:

public 
static class JsonResultTestExtensions{    

public 
static string GenerateOutputJson(this JsonResult result)    {
var serializer = new JavaScriptSerializer();
var output = serializer.Serialize(result.Data);
return output;
    }
}

Reparem que este extension method será criado no projeto de testes, ou em uma DLL a ser referenciada apenas nos projetos de testes!E nosso teste ficaria assim:

[TestMethod]
public void TestMethod1(){
var controller = new HomeController();
var result = controller.DadosJson();
    Assert.AreEqual(@"{
"Id"":10,""Nome"":""Vinicius""}
", result.GenerateOutputJson());
    }

Bem mais limpo!

Outras formas...

Existem outras formas de realizar esta tarefa, no entanto esta me pareceu a mais simples. Uma outra envolve chamar o método ExecuteResult, porém para isso precisamos mockar 3 objetos e configurar callbacks, o que não fica muito intuitivo, sendo que o que precisamos é apenas executar aquelas duas linhas assim como o ASP.NET MVC fará.Se quiserem ver como seriam estas outras maneiras, podem dar uma olhada neste link aqui.

Resuminho

Com isto conseguimos mais uma forma de testar nossas actions que retornam dados Json. Se precisamos de fato validar a estrutura Json destas informações, agora já temos uma maneira simples de fazer isso.Se precisarmos validar os dados, sem nos preocupar com o Json, podemos trabalhar conforme mostrado neste post aqui.O importante é escrevermos os testes, de forma que eles nos ajudem da melhor forma possível, e nos possibilitem deixar o sistema mais "previsível" quando futuras mudanças ocorrerem.

Abraços, e espero que seja útil.Vinicius Quaiato.

Voltar

Fork me on GitHub