Injectez des dépendances dans vos tests avec AutoMock

Auteur du billet de blog : Nicolas Hilaire - Neotech Solutions

Nicolas Hilaire

Consultant .NET
  Publié le mardi 21 juin 2016

Artisan logiciel particulièrement intéressé par les technologies .NET. Polyvalent et curieux, je suis néanmoins à l'écoute des autres technologies du marché. MVP (Microsoft Most Valuable Professional) de 2007 à 2014, je suis également auteur d'un ouvrage pour apprendre le C#, à destination des débutants et de plusieurs MOOCs sur le C#, Windows Phone ou ASP.NET MVC...

Autofac est un des container IOC pour .NET les plus populaires. Il est très facilement utilisable et permet de faire simplement de l’injection de dépendances. Mais ce n’est pas lui le sujet de ce billet car vous l’avez sans doute déjà utilisé dans vos applications (sinon, je vous encourage à aller lire la documentation à ce sujet). Par contre, je vais vous parler plutôt de comment l’utiliser avec Moq dans vos tests unitaires grâce à la bibliothèque AutoMock, disponible dans le package NuGet Autofac.Extras.Moq.AutoMock.

Et pour ce faire, mettons en place un petit squelette d’utilisation d’Autofac ainsi qu’un test unitaire qui bouchonnera les dépendances avec Moq, et pour cela je vais utiliser une application console.

On va créer quelques classes pour se la jouer site d’e-commerce et récupérer un produit. Très light, promis. Voici la classe Produit :

Ensuite, on crée un petit repository pour chercher le produit, et comme il s’agit d’un composant technique potentiellement interchangeable, nous ajoutons une interface.

Vous remarquerez que la classe CatalogueRepository accepte un loggueur en paramètre du constructeur, car c’est important de pouvoir logguer dans notre repository. Et puis les logs c’est bien !

Enfin, créons un service métier, qui prendra un catalog en paramètre, ainsi que de quoi logguer (oui, je suis un psychopathe des logs) :

Bon, classique oserai-je dire… Vous avez sans doute fait ça des centaines de fois.

Maintenant, il n’y a plus qu’à construire le container IOC afin qu’il nous fasse l’injection de dépendances. D’abord, on rajoute Autofac :

 

 

Puis, dans la méthode Main, on réalise la construction :

Encore une fois, je reste très light car il ne s’agit pas d’une présentation d’Autofac, qui permet de faire beaucoup plus de choses que ça.

Un détail important : non, ce n’est pas une obligation d’utiliser une interface pour faire de l’injection de dépendance, la preuve je n’en ai pas pour mon CatalogueService. (même si c’est vrai qu’avec un framework de simulacre comme Moq, c’est quand même beaucoup plus simple).

Passons aux tests.

Je crée une nouvelle classe pour tester mon fameux service. Voilà ce qu’on pourrait faire, en ayant au préalable ajouté le package NuGet de Moq :

 

Et tout ça fonctionne bien. Parfait. On est content.

Fin de l’histoire ?

Non, car bien sûr vous allez ajouter des fonctionnalités, créer de plus en plus de tests, en bons développeurs que vous êtes. Et je ne peux que vous en féliciter.

Jusqu’au jour où vous allez injecter une nouvelle dépendance dans le constructeur de CatalogueService car vous avez besoin d’un nouveau repository pour aller récupérer le stock ou que sais-je d’autre. Eh bien, qu’à cela ne tienne, c’est très facile avec Autofac. Il suffit juste d’enregistrer une nouvelle classe et le tour est joué.

Sauf que vous devez maintenant changer tous les constructeurs explicites de CatalogueService, notamment tous ceux qui sont dans les classes de tests, pour y injecter manuellement une nouvelle dépendance. Dans la plupart des cas, elle sera nulle pour les anciens tests car vous respectez sans aucun souci les principes SOLID. Mais en tous cas, elle sera bouchonnée pour vos nouveaux tests.

Toujours est-il qu’il va y avoir un paquet de constructeur à modifier. Alors, oui, vous pourriez créer une méthode factory qui abstrait l’utilisation de tous ces constructeurs, mais si j’écris ce billet, c’est qu’il y a une autre solution. Je vous présente AutoMock.

Et comble de l’originalité, il se présente sous la forme d’un package NuGet :

 

 

Et grâce à ce package, on pourra automatiquement créer des dépendances bouchonnées grâce à Autofac. Voyez par exemple comment réécrire mon précédent test :

On utilise toujours le même principe pour bouchonner les dépendances, sachant que je n’ai même plus besoin de m’occuper de la dépendance ILog dont je ne bouchonnais pas le comportement. Et la création du service bouchonné se fait via AutoMock, sans appel explicite à new.

Alors, elle est pas belle la vie ?