Créer des tests unitaires pour vos applications MVC

Louis-Guillaume MORAND (Traduction)

Apprenez comment créer un test unitaire pour des actions contrôleur. Dans ce tutoriel, Stephen Walther démontre comment tester si une action contrôleur retourne une vue particulière, retourne un set de données, ou retourne un type différent de résultat d’action. ♪

- Titre : Créer des tests unitaires pour vos applications MVC

- Auteur : Louis-Guillaume MORAND (Traduction)

- Parution : 1 mai 2009

- Licence : Copyright ® 2009 Equipe dotnet. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- Traduction

- Introduction

- Création du contrôleur à tester

- Tester la vue retournée par un contrôleur

- Tester le View Data retourné par un contrôleur

- Tester le résultat d’action retourné par un contrôleur

- Conclusion

- Remerciements

Traduction

Cet article est la traduction la plus fidèle possible de l’article original : Creating Unit Tests for ASP.NET MVC Applications

Introduction

Le but de ce tutoriel est de montrer comment vous pouvez utiliser des tests unitaires pour les contrôleurs de vos applications MVC. Nous allons discuter comment construire trois types de tests unitaires. Vous allez apprendre comment tester la vue retournée par une action contrôleur, comment tester le View Data retourné par une action contrôleur et comment tester si oui ou non une action contrôleur vous redirige vers une seconde action contrôleur.

Création du contrôleur à tester

Commençons par créer le contrôleur que nous souhaitons tester. Le contrôleur, nommé ProductController, est tel que le code suivant :

ProductController.cs

using System;
using System.Web.Mvc;

namespace Store.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
// Add action logic here
throw new NotImplementedException();
}

public ActionResult Details(int Id)
{
return View("Details");
}
}
}

Le ProductController contient deux méthodes d’action nommées Index() et Details(). Les deux actions renvoient une vue. Notez que l’action Details() accepte un paramètre de type entier nommé Id.

Tester la vue retournée par un contrôleur

Imaginez que nous voulions tester si oui ou non le ProductController retourne la bonne vue. Nous voulons être sûrs que lorsque l’action ProductController.Details() est invoquée, la vue Details est retournée. La classe Test présentée dans le code suivant contient un test unitaire qui teste la vue retournée par l’action ProductController.Details().

ProductControllerTest.cs

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Store.Controllers;

namespace StoreTests.Controllers
{
[TestClass]
public class ProductControllerTest
{
[TestMethod]
public void TestDetailsView()
{
var controller = new ProductController();
var result = controller.Details(2) as ViewResult;
Assert.AreEqual("Details", result.ViewName);
}
}
}

La classe précédente inclut une méthode de test nommée TestDetailsView(). Cette méthode contient trois lignes de code. La première ligne crée une nouvelle instance de la classe ProductController. La seconde ligne invoque l’action Details() et enfin la dernière ligne vérifie si oui oui non la vue retournée par l’action Details() est bien la vue Details.

La propriété ViewResult.ViewName représente le nom de la vue retournée par un contrôleur. Attention, il existe deux façons dont un contrôleur peut retourner une vue. Il peut la retourner explicitement comme ceci :

public ActionResult Details(int Id)
{
return View("Details");
}

Ou alors, le nom de la vue peut être deviné depuis le nom du contrôleur, comme ceci :

public ActionResult Details(int Id)
{
return View();
}

Cette action contrôleur retourne également une vue nommée Details. Pourtant, le nom de la vue est deviné depuis le nom de l’action. Si vous voulez tester le nom de la vue, alors vous devez explicitement retourner le nom de la vue depuis l’action contrôleur.

Vous pouvez lancer le test unitaire soit en tapant la combinaison de touche Ctrl-R,A ou en cliquant sur le bouton Lancer tous les tests dans la solution. Si le test réussit, vous verrez la fenêtre de résultats de la seconde image.

Tester le View Data retourné par un contrôleur

Un contrôleur MVC passe des données à une vue en utilisant quelque chose nommé View Data. Par exemple, imaginez que vous vouliez afficher les détails pour un produit particulier lorsque vous invoquez l’action ProductController.Details(). Dans ce cas, vous pouvez créer une instance d’une classe Produit (défini dans votre modèle) et passer cette instance à la vue Details en tirant avantage du View Data.

Le ProductController modifié dans l’extrait de code suivant inclut une action Details mise à jour qui retourne un Product.

ProductController.cs

using System;
using System.Web.Mvc;

namespace Store.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
// Add action logic here
throw new NotImplementedException();
}

public ActionResult Details(int Id)
{
var product = new Product(Id, "Laptop");
return View("Details", product);
}
}
}

Tout d’abord, l’action Details crée une nouvelle instance de la classe Product qui représente un ordinateur portable. Ensuite, l’instance de la classe Product est passée en tant que second paramètre à la méthode View().

Vous pouvez écrire des tests unitaires pour tester si les données attendues sont bien contenues dans le View Data retourné. Le test unitaire suivant vérifie si oui ou non, un Product représentant un ordinateur portable est bien retourné lorsque vous appelez la méthode d’action Details() du contrôleur ProductController.

ProductControllerTest.cs

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Store.Controllers;

namespace StoreTests.Controllers
{
[TestClass]
public class ProductControllerTest
{
[TestMethod]
public void TestDetailsViewData()
{
var controller = new ProductController();
var result = controller.Details(2) as ViewResult;
var product = (Product) result.ViewData.Model;
Assert.AreEqual("Laptop", product.Name);
}
}
}

Dans le code précédent, la méthode TestDetailsView() teste le View Data retourné lors de l’invocation de la méthode Details(). La propriété ViewData.Model contient le produit passé à la vue. Le test vérifie simplement que le produit transmis a le nom Laptop.

Tester le résultat d’action retourné par un contrôleur

Une action contrôleur pourrait retourner différents types de résultats dépendant des valeurs des paramètres que vous passez à l’action. Une action contrôleur peut ainsi retourner différents types de résultats tels qu’un ViewResult, un RedirectToRouteResult, ou un JsonResult.

Par exemple, l’action modifiée Details suivante retourne la vue Details lorsque vous passez un ID produit valide. Si vous passez un mauvais identifiant, un ID avec une valeur inférieure à 1, alors vous êtes redirigés vers l’action Index().

ProductController.cs

using System;
using System.Web.Mvc;
namespace Store.Controllers
{
public class ProductController : Controller
{
public ActionResult Index()
{
// Add action logic here
throw new NotImplementedException();
}
public ActionResult Details(int Id)
{
if (Id < 1)
return RedirectToAction("Index");
var product = new Product(Id, "Laptop");
return View("Details", product);
}
}
}

Vous pouvez tester le comportement de l’action Details() avec le test unitaire du code suivant. Le test unitaire vérifie que vous êtes bien redirigé vers la vue Index quand un id avec la valeur -1 est passé à la méthode Details.

ProductControllerTest.cs

using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Store.Controllers;
namespace StoreTests.Controllers
{
[TestClass]
public class ProductControllerTest
{
[TestMethod]
public void TestDetailsRedirect()
{
var controller = new ProductController();
var result = (RedirectToRouteResult) controller.Details(-1);
Assert.AreEqual("Index", result.Values["action"]);
}
}
}

Lorsque vous appelez la méthode RedirectToAction() dans une action contrôleur, l’action retourne un RedirectToRouteResult. Le test vérifie si le RedirectToRouteResult va rediriger l’utilisateur vers une action contrôleur nommée Index.

Conclusion

Dans ce tutoriel, vous avez appris comment construire des tests unitaires pour les actions contrôleur MVC. D’abord, vous avez appris comment vérifier si la vue retournée par une action contrôleur est la bonne. Vous avez appris comment utiliser la propriété ViewResult.ViewName pour vérifier le nom d’une vue.

Ensuite, nous avons examiné comment vous pouviez tester le contenu d’un View Data. Vous avez appris comment vérifier si le bon produit est retourné dans le View Data après avoir appelé une action contrôleur.

Pour finir, nous avons discuté de comment vous pouviez tester différents types de résultats d’action qui sont retournés par des actions contrôleur. Vous avez appris comment tester si un contrôleur renvoie un ViewResult ou un RedirectToRouteResult.

Remerciements

Merci à dourou05 pour les corrections apportées à l’article.