Monthly Archives: January 2018

Les tests unitaires en Java: Given, When, Then (ou Arrange, Act, Assert suivant l’idéologie)

Un test unitaire doit être découpé en trois parties.

L’instanciation (Given ou Arrange): Cette partie décrit l’état au début du test. C’est la définition du scénario.

L’éxécution (When ou Act): Le comportement à vérifier. Un seul comportement à vérifier par test !!!

La vérification (When ou Assert): La description de ce que l’on attend en sortie du test.

Ci dessous, un exemple définit par Martin Fowler:

Si le test ne rentre pas dans cette structure, c’est qu’il doit être refactoré.

Voici un exemple de ce que ça donne en Java:

Les tests unitaires en Java: Instanciation d’objets en série

Lorsque nous créons des tests unitaires à la chaîne, un des soucis qui se pose rapidement est l’instanciation répétée d’objets souvent similaires pour ne pas dire identiques. On se retrouve vite avec des copier coller en série, qui, au premier refactoring de code, se transforme en corrections en série.

Cette approche basique n’est pas viable pour maintenir une série de tests sur un projet de grande envergure. Un changement sur une classe business object ne doit avoir qu’un impact limité sur les tests qui l’utilisent.

Les tests unitaires sont là pour être efficaces sur le long terme et pour nous faire gagner du temps.

Le pattern Test Data Builder

Il s’agit d’une factory qui permet d’instancier des objets business. Prenons l’exemple d’un projet pour une banque qui servirait à gérer un portefeuille de clients. La classe business object du client serait comme suit:

La création de cet objet et de tous ces sous objet peut être très fastidieux. Pour cela, le pattern Test Data Builder va nous permettre de faciliter la création des tests mais aussi la maintenance évolutive. Voir l’exemple d’utilisation ci-dessous:

L’instanciation apparaît maintenant très clairement, contrairement à ce que pourrait produire une série de setters avec des instanciations à la chaîne. Il est aussi beaucoup plus facile de suivre les différents cas de tests On sait de suite quel cas de test plante et quel est le sujet exact qui pose un soucis. Et en plus, les Test Data Builders améliorent la maintenabilité des tests en séparant bien les données de la logique. La création des objets métiers est encapsulée, et ne vient pas polluer le code des tests.

Le builder est comme suit:

On peut ainsi créer des cas réutilisables à souhait, pour couvrir au maximum les cas de tests du projet. Le product owner peut ainsi décrire les clients typiques et il est aisé de les recréer dans le builder. Il est notable que j’ai utilisé des appels statiques pour créer les sous objets du client. Ce choix va dépendre des besoins et contraintes spécifiques à chaque projet et structure de données.

Concernant les champs propres des objets instanciés, il est judicieux de choisir des valeurs limites. Ainsi, si le champs client_name en base est sur 256 caractères, l’initialisation dans le builder pourra être faite avec un une chaîne aléatoire de 256 caractères.