Tworzenie testów jednostkowych dla aplikacji ASP.NET MVC (VB)

Autor: Stephen Walther

Dowiedz się, jak tworzyć testy jednostkowe dla akcji kontrolera. W tym samouczku Stephen Walther pokazuje, jak sprawdzić, czy akcja kontrolera zwraca określony widok, zwraca określony zestaw danych lub zwraca inny typ wyniku akcji.

Celem tego samouczka jest pokazanie, jak można pisać testy jednostkowe dla kontrolerów w aplikacjach ASP.NET MVC. Omawiamy sposób tworzenia trzech różnych typów testów jednostkowych. Dowiesz się, jak przetestować widok zwrócony przez akcję kontrolera, jak przetestować dane widoku zwrócone przez akcję kontrolera oraz sprawdzić, czy jedna akcja kontrolera przekierowuje Użytkownika do drugiej akcji kontrolera.

Tworzenie kontrolera w ramach testu

Zacznijmy od utworzenia kontrolera, który zamierzamy przetestować. Kontroler o nazwie ProductController, znajduje się w liście 1.

Lista 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

Zawiera ProductController dwie metody akcji o nazwie Index() i Details(). Obie metody akcji zwracają widok. Zwróć uwagę, że Details() akcja akceptuje parametr o nazwie Id.

Testowanie widoku zwróconego przez kontroler

Załóżmy, że chcemy przetestować, czy funkcja ProductController zwraca właściwy widok. Chcemy upewnić się, że po ProductController.Details() wywołaniu akcji zostanie zwrócony widok Szczegóły. Klasa testowa w liście List 2 zawiera test jednostkowy do testowania widoku zwróconego ProductController.Details() przez akcję.

Lista 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

Klasa w liście 2 zawiera metodę testową o nazwie TestDetailsView(). Ta metoda zawiera trzy wiersze kodu. Pierwszy wiersz kodu tworzy nowe wystąpienie ProductController klasy. Drugi wiersz kodu wywołuje metodę akcji kontrolera Details() . Na koniec ostatni wiersz kodu sprawdza, czy widok zwrócony przez Details() akcję jest widokiem Szczegóły.

Właściwość ViewResult.ViewName reprezentuje nazwę widoku zwróconego przez kontroler. Jedno duże ostrzeżenie dotyczące testowania tej właściwości. Istnieją dwa sposoby zwracania widoku przez kontroler. Kontroler może jawnie zwrócić widok podobny do następującego:

Function Details(ByVal Id As Integer)
     Return View("Details")
End Function

Alternatywnie nazwę widoku można wywnioskować z nazwy akcji kontrolera w następujący sposób:

Function Details(ByVal Id As Integer)
     Return View()
End Function

Ta akcja kontrolera zwraca również widok o nazwie Details. Jednak nazwa widoku jest wywnioskowana z nazwy akcji. Jeśli chcesz przetestować nazwę widoku, musisz jawnie zwrócić nazwę widoku z akcji kontrolera.

Test jednostkowy można uruchomić na liście 2, wprowadzając kombinację klawiatury Ctrl-R, A lub klikając przycisk Uruchom wszystkie testy w rozwiązaniu (zobacz Rysunek 1). Jeśli test zakończy się pomyślnie, w rysunku 2 zostanie wyświetlone okno Wyniki testu.

Uruchamianie wszystkich testów w rozwiązaniu

Rysunek 01. Uruchamianie wszystkich testów w rozwiązaniu (kliknij, aby wyświetlić obraz pełnowymiarowy)

Sukces!

Rysunek 02. Sukces! (Kliknij, aby wyświetlić obraz o pełnym rozmiarze)

Testowanie danych widoku zwróconych przez kontrolera

Kontroler MVC przekazuje dane do widoku przy użyciu elementu o nazwie View Data. Załóżmy na przykład, że chcesz wyświetlić szczegóły określonego produktu podczas wywoływania ProductController Details() akcji. W takim przypadku możesz utworzyć wystąpienie Product klasy (zdefiniowanej w modelu) i przekazać wystąpienie do Details widoku, korzystając z funkcji View Data.

Zmodyfikowany ProductController element w liście 3 zawiera zaktualizowaną Details() akcję zwracającą produkt.

Lista 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

Najpierw akcja Details() tworzy nowe wystąpienie Product klasy reprezentującej komputer przenośny. Następnie wystąpienie Product klasy jest przekazywane jako drugi parametr do View() metody.

Możesz napisać testy jednostkowe, aby sprawdzić, czy oczekiwane dane są zawarte w danych widoku. Test jednostkowy w artykule Lista 4 sprawdza, czy produkt reprezentujący komputer przenośny jest zwracany podczas wywoływania ProductController Details() metody akcji.

Lista 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 liście 4 TestDetailsView() metoda testuje dane widoku zwrócone przez wywołanie Details() metody . Właściwość ViewData jest uwidoczniona jako właściwość zwrócona ViewResult przez wywołanie Details() metody. Właściwość ViewData.Model zawiera produkt przekazany do widoku. Test po prostu sprawdza, czy produkt zawarty w danych widoku ma nazwę Laptop.

Testowanie wyniku akcji zwróconego przez kontroler

Bardziej złożona akcja kontrolera może zwracać różne typy wyników akcji w zależności od wartości parametrów przekazanych do akcji kontrolera. Akcja kontrolera może zwracać różne typy wyników akcji, w tym ViewResult, RedirectToRouteResultlub JsonResult.

Na przykład zmodyfikowana Details() akcja w pozycji Lista 5 zwraca Details widok po przekazaniu prawidłowego identyfikatora produktu do akcji. W przypadku przekazania nieprawidłowego identyfikatora produktu — identyfikatora o wartości mniejszej niż 1 — nastąpi przekierowanie do Index() akcji.

Lista 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

Zachowanie akcji można przetestować Details() za pomocą testu jednostkowego w pozycji Lista 6. Test jednostkowy na liście 6 sprawdza, czy nastąpi przekierowanie do Index widoku, gdy identyfikator z wartością -1 zostanie przekazany do Details() metody.

Lista 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

Po wywołaniu RedirectToAction() metody w akcji kontrolera akcja kontrolera zwraca wartość RedirectToRouteResult. Test sprawdza, czy RedirectToRouteResult użytkownik przekierowuje użytkownika do akcji kontrolera o nazwie Index.

Podsumowanie

W tym samouczku przedstawiono sposób kompilowania testów jednostkowych dla akcji kontrolera MVC. Najpierw pokazano, jak sprawdzić, czy właściwy widok jest zwracany przez akcję kontrolera. Wiesz już, jak użyć ViewResult.ViewName właściwości w celu zweryfikowania nazwy widoku.

Następnie sprawdziliśmy, jak można przetestować zawartość elementu View Data. Wiesz już, jak sprawdzić, czy właściwy produkt został zwrócony View Data po wywołaniu akcji kontrolera.

Na koniec omówiliśmy sposób testowania, czy z akcji kontrolera są zwracane różne typy wyników akcji. Pokazano, jak sprawdzić, czy kontroler zwraca obiekt ViewResult , czy RedirectToRouteResult.