Criação de testes de unidade para aplicativos do ASP.NET MVC (VB)
por Stephen Walther
Saiba como criar testes de unidade para ações do controlador. Neste tutorial, Stephen Walther demonstra como testar se uma ação do controlador retorna uma exibição específica, retorna um determinado conjunto de dados ou retorna um tipo diferente de resultado de ação.
O objetivo deste tutorial é demonstrar como você pode escrever testes de unidade para os controladores em seus aplicativos ASP.NET MVC. Discutimos como criar três tipos diferentes de testes de unidade. Você aprenderá a testar a exibição retornada por uma ação do controlador, como testar os Dados de Exibição retornados por uma ação do controlador e como testar se uma ação do controlador redireciona ou não você para uma segunda ação do controlador.
Criando o controlador em Teste
Vamos começar criando o controlador que pretendemos testar. O controlador, chamado ProductController
, está contido na Listagem 1.
Listagem 1 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
Return View("Details")
End Function
End Class
O ProductController
contém dois métodos de ação chamados Index()
e Details()
. Ambos os métodos de ação retornam uma exibição. Observe que a ação Details()
aceita um parâmetro chamado Id.
Testando a exibição retornada por um controlador
Imagine que queremos testar se o retorna ou não a ProductController
exibição certa. Queremos garantir que, quando a ação ProductController.Details()
for invocada, a exibição Detalhes seja retornada. A classe de teste na Listagem 2 contém um teste de unidade para testar a exibição retornada pela ação ProductController.Details()
.
Listagem 2 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsView()
Dim controller As New ProductController()
Dim result As ViewResult = controller.Details(2)
Assert.AreEqual("Details", result.ViewName)
End Sub
End Class
A classe na Listagem 2 inclui um método de teste chamado TestDetailsView()
. Esse método contém três linhas de código. A primeira linha de código cria uma nova instância da ProductController
classe . A segunda linha de código invoca o método de ação do Details()
controlador. Por fim, a última linha de código verifica se a exibição retornada pela Details()
ação é ou não a exibição Detalhes.
A ViewResult.ViewName
propriedade representa o nome da exibição retornada por um controlador. Um grande aviso sobre como testar essa propriedade. Há duas maneiras de um controlador retornar uma exibição. Um controlador pode retornar explicitamente uma exibição como esta:
Function Details(ByVal Id As Integer)
Return View("Details")
End Function
Como alternativa, o nome da exibição pode ser inferido do nome da ação do controlador desta forma:
Function Details(ByVal Id As Integer)
Return View()
End Function
Essa ação do controlador também retorna uma exibição chamada Details
. No entanto, o nome da exibição é inferido do nome da ação. Se você quiser testar o nome da exibição, deverá retornar explicitamente o nome da exibição da ação do controlador.
Você pode executar o teste de unidade na Listagem 2 inserindo a combinação de teclado Ctrl-R, A ou clicando no botão Executar Todos os Testes na Solução (consulte a Figura 1). Se o teste for aprovado, você verá a janela Resultados do Teste na Figura 2.
Figura 01: Executar todos os testes na solução (clique para exibir a imagem em tamanho real)
Figura 02: Sucesso! (Clique para exibir a imagem em tamanho real)
Testando os dados de exibição retornados por um controlador
Um controlador MVC passa dados para uma exibição usando algo chamado View Data
. Por exemplo, imagine que você deseja exibir os detalhes de um produto específico ao invocar a ação ProductController Details()
. Nesse caso, você pode criar uma instância de uma Product
classe (definida em seu modelo) e passar a instância para a exibição Details
aproveitando o View Data
.
O modificado ProductController
na Listagem 3 inclui uma ação atualizada Details()
que retorna um Produto.
Listagem 3 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
Dim product As New Product(Id, "Laptop")
Return View("Details", product)
End Function
End Class
Primeiro, a ação Details()
cria uma nova instância da Product
classe que representa um computador laptop. Em seguida, a instância da Product
classe é passada como o segundo parâmetro para o View()
método .
Você pode escrever testes de unidade para testar se os dados esperados estão contidos nos dados de exibição. O teste de unidade na Listagem 4 testa se um Produto que representa ou não um computador laptop é retornado quando você chama o método de ProductController Details()
ação.
Listagem 4 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsViewData()
Dim controller As New ProductController()
Dim result As ViewResult = controller.Details(2)
Dim product As Product = result.ViewData.Model
Assert.AreEqual("Laptop", product.Name)
End Sub
End Class
Na Listagem 4, o TestDetailsView()
método testa os Dados de Exibição retornados invocando o Details()
método . O ViewData
é exposto como uma propriedade no ViewResult
retornado invocando o Details()
método . A ViewData.Model
propriedade contém o produto passado para a exibição. O teste simplesmente verifica se o produto contido nos Dados de Exibição tem o nome Laptop.
Testando o resultado da ação retornado por um controlador
Uma ação de controlador mais complexa pode retornar diferentes tipos de resultados de ação, dependendo dos valores dos parâmetros passados para a ação do controlador. Uma ação do controlador pode retornar uma variedade de tipos de resultados de ação, incluindo um ViewResult
, RedirectToRouteResult
ou JsonResult
.
Por exemplo, a ação modificada Details()
na Listagem 5 retorna a Details
exibição quando você passa uma ID de produto válida para a ação. Se você passar uma ID de produto inválida , uma ID com um valor menor que 1, você será redirecionado para a ação Index()
.
Listagem 5 – ProductController.vb
Public Class ProductController
Inherits System.Web.Mvc.Controller
Function Index()
' Add action logic here
Throw New NotImplementedException()
End Function
Function Details(ByVal Id As Integer)
If Id < 1 Then
Return RedirectToAction("Index")
End If
Dim product As New Product(Id, "Laptop")
Return View("Details", product)
End Function
End Class
Você pode testar o comportamento da ação Details()
com o teste de unidade na Listagem 6. O teste de unidade na Listagem 6 verifica se você é redirecionado para a Index
exibição quando uma ID com o valor -1 é passada para o Details()
método .
Listagem 6 – ProductControllerTest.vb
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports System.Web.Mvc
Imports Store
<TestClass()> Public Class ProductControllerTest
<TestMethod()> Public Sub TestDetailsRedirect()
Dim controller As New ProductController()
Dim result As RedirectToRouteResult = controller.Details(-1)
Assert.AreEqual("Index", result.Values("action"))
End Sub
End Class
Quando você chama o RedirectToAction()
método em uma ação de controlador, a ação do controlador retorna um RedirectToRouteResult
. O teste verifica se o RedirectToRouteResult
redirecionará o usuário para uma ação do controlador chamada Index
.
Resumo
Neste tutorial, você aprendeu a criar testes de unidade para ações do controlador MVC. Primeiro, você aprendeu a verificar se a exibição certa é retornada por uma ação do controlador. Você aprendeu a usar a ViewResult.ViewName
propriedade para verificar o nome de uma exibição.
Em seguida, examinamos como você pode testar o conteúdo de View Data
. Você aprendeu a marcar se o produto certo foi retornado View Data
depois de chamar uma ação do controlador.
Por fim, discutimos como você pode testar se diferentes tipos de resultados de ação são retornados de uma ação do controlador. Você aprendeu a testar se um controlador retorna um ViewResult
ou um RedirectToRouteResult
.