Skip to main content

Mockito ou comment simuler des objets dans les tests unitaires


Enfin un framework qui me réconcilie avec les tests unitaires, non pas que j'étais très fâché, les tests unitaires sont nécessaires mais je ne prenais pas un grand plaisir à les faire.
Je travaille en ce moment sur un projet de client/serveur basé sur les excellents framework Netty et Protobuf et écrire des test unitaires sur ce type de projet très technique peut se révéler être assez difficile.
Pourtant depuis peu je dois confesser que je prend un certain plaisir à en écrire, ceci depuis que j'ai découvert Mockito.

Mockito ça sert à quoi ?
L'un des problèmes avec les tests unitaires ce sont les objets qui sont mis en jeu. Certains objets sont en effet très difficile à instancier, il peut être même impossible de le faire si on est en phase de spécification et que seule l'interface a été écrite.
Il est encore plus difficile de contrôler leur comportement pour recréer des contextes particuliers d’exécution comme recréer un contexte d'erreur.
C'est là qu'intervient Mockito : Mockito permet de créer des classes "fantoches", des "marionnettes" à partir de n'importe quelle classe ou même à partir d'une simple interface. En anglais on appelle ça des "mock objects".
Cette classe vous allez pouvoir contrôler finement son comportement, comme les valeurs de retour de ses méthodes : c'est qu'on appelle le "stubbing".

Exemples

Je vais reprendre les exemples du site, ceux basés sur l'interface List, mais avec mes propres commentaires :

1. Création de "mock objects"

import static org.mockito.Mockito.*;
List mockedList = mock(List.class);

Dans cette exemple nous venons de créer un objet à partir de l'interface List. Cet objet implémente l'interface par contre son comportement est pour le moment assez limité, un appel à mockedList.get(0) retournera null.
Pour controler son comportement nous allons faire du "stubbing"

2. Le "stubbing"


when(mockedList.get(0)).thenReturn("toto");

Maintenant un appel à mockedList.get(0)retournera la chaine "toto".
Si l'on souhaite répondre "toto" pour n'importe qu'elle indice de la liste :

when(mockedList.get(anyInt())).thenReturn("toto");

Maintenant un appel à mockedList.get(indice) avec n'importe quel entier en indice retournera la chaine "toto".

3. Vérifier les appels
Il peut être intéressant de contrôler qu'une méthode a bien été appelée et avec les bon arguments en paramètre.

System.out.println(mockedList.get(888));
// Doit afficher "toto" sur la sortie standard
// Si l'on souhaite vérifier qu'il y a bien eu un appel à la méthode get avec comme paramètre 888
verify(mockedList).get(888);

Voilà pour la petite intro, les autres fonctionnalités sont décrites ici. Au passage Mockito est un bon tremplein vers le Behaviour Driven Developement alors pourquoi se priver ?

Comments

Popular posts from this blog

Orientée colonnes ?

Les bases NoSQL sont arrivées avec leur cortège de nouveautés et pour certaines d'entre elles une notion héritée de BigTable : celle de base de donnée orientée colonne. Cependant faire le lien entre l'article de Wikipedia et comprendre ce que permet réellement un base de donnée comme HBase n'est pas une chose évidente. En effet le simple fait de définir cette notion ne suffit pas toujours a bien comprendre quels sont les principes de conception du monde SQL qui peuvent être oubliés et ceux qui doivent être appris. Colonne or not colonne ? Prenons un modèle très simple de donnée et essayons de le transposer dans un modèle "orienté colonne": Comme on peut le voir on est passé d'un modèle à 2 dimensions (ligne x colonne) vers un modèle où une valeur est accédée au travers de 2  coordonnées qui sont ici (ligne, colonne) Cette notion de coordonnées est  importante  (c'est pour ça que je la met en gras 2 fois de suite) si l'on veut c

Row Count : HBase Aggregation example

With the coprocessors HBase 0.92 introduces a new way to process data directly on a region server. As a user this is definitively a very exciting feature : now you can easily define your own distributed data services. This post is not intended to help you how to define them (i highly recommend you to watch this presentation if you want to do so) but to quickly presents the new aggregation service shipped with HBase 0.92 that is built upon the endpoint coprocessor framework. 1. Enable AggregationClient coprocessor You have two choices : You can enable aggregation coprocessor on all your tables by adding the following lines to hbase-site.xml : <property> <name>hbase.coprocessor.user.region.classes</name> <value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value> </property> or ...you can enable coprocessor only on a table throught the HBase shell : 1. disable the table hbase> disable ' mytable ' 2.

HBase + Subversion + Eclipse + Windows

HBase + Subversion + Eclipse + Windows (it should be easy to adapt for Linux) Update : please note that since HBase-4336 / HBase 0.96 the source tree is split in more than one Maven module this post is no more relevant, i have created a new post on this subject : http://michaelmorello.blogspot.fr/2012/06/hbase-096-eclipse-maven.html This is a simple setup in order to play with the source code of HBase under Microsoft Windows. Since HBase use some Unix specific commands like chmod the only requirements here are  Cygwin and a working Maven 3 environment. (It is obvious that you need Java and Eclipse , but you DON'T need anything else like the Eclipse Maven plugin or any SSH configuration) 1. Checkout the source code The first step is to check out the source code from the Subversion repository. I did it under my cygwin home repository. In this example i want to play with the 0.90 branch : svn co http://svn.apache.org/repos/asf/hbase/branches/0.90/ hbase-0.90