1 / 14

MOCK

MOCK. Définition. Simuler le comportement d'un autre objet concret de façon maitrisée. Utilisé pour les tests unitaires Permet aux tests unitaires de se concentrer sur les tests du code de la méthode sans avoir à se préoccuper des dépendances.

locke
Télécharger la présentation

MOCK

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. MOCK

  2. Définition • Simuler le comportement d'un autre objet concret de façon maitrisée. • Utilisé pour les tests unitaires • Permet aux tests unitaires de se concentrer sur les tests du code de la méthode sans avoir à se préoccuper des dépendances. • Simuler le comportement d'un objet permettant de réaliser les tests de l'objet de façon isolée et répétable. • Cette double fonctionnalité permet dans un test unitaire de faire des tests sur l'état et des tests sur le comportement

  3. Type de mock • Il existe deux grands types d'objets mock • Statique : ce sont des classes écrites ou générées par le développeur • Dynamique : ils sont mis en œuvre via un framework • Les objets mock peuvent être codés manuellement ou utiliser un framework qui va permettre de les générer dynamiquement. • L'avantage des mocks dynamiques c'est qu'aucune classe implicite n'a besoin d'être écrite.

  4. Quand utiliser des mocks ? • L'objet réel a un comportement non déterministe (il produit des résultats imprévisibles, comme une date ou la température actuelle) • L'objet réel est difficile à mettre en place, ou est lent (cas d'une base de données, ou d'un service web) • Le comportement de l'objet réel est difficile à déclencher (par exemple, un problème de réseau) • L'objet réel a (ou est) une interface utilisateur • Le test doit demander à l'objet la manière dont elle est utilisée (par exemple, confirmer qu'une fonction a été effectivement appelée) • L'objet réel n'existe pas encore (un problème courant lorsque l'on doit interagir avec d'autres équipes ou de nouveaux systèmes matériels)

  5. Exemple: Utilisation dans les tests unitaires • Classes ont généralement des dépendances entre elles • Idée pour tester un code unitaire => tester la plus petite unité de code possible => tester le code de la méthode • Problème => Classes utilisées dans le code d’une méthode peut faire appel à un ou plusieurs autres objets • But => Ce n’est pas de tester ces objets mais de tester le code de la méthode => ne pas tester les dépendances • Solution => Mock qui permette de s’assurer que les objets dépendants fournissent les réponses désirées à leur invocation • Finalité => Si le code de ma chine fonctionne & les dépendances fonctionnent aussi => OK

  6. Mise en œuvre des objets de type mock • Avantage à utiliser des objets mock => force le code à être écrit ou adapté via des refactoring pour qu'il respecte une conception qui permettre de rendre le code testable • Objet de type mock possède donc la même interface que l'objet qu'il doit simuler, ce qui permet d'utiliser le mock ou une implémentation concrète de façon transparente pour l'objet qui l'invoque. • Aussi capables de vérifier les invocations qui sont faites sur le mock : nombres d'invocations, paramètres fournis, ordre d'invocations, ... • Mise en œuvre d’un mock suit plusieurs étapes: • définir le comportement du mock : méthodes invoquées, paramètres fournis, valeurs de retour ou exception ... • exécuter le test en invoquant la méthode à tester • vérifier des résultats du test • vérifier les invocations du ou des objets de type mock : nombre d'invocations, ordre d'invocations, ...

  7. Utilité • Les objets de type mock peuvent être utilisés dans différentes circonstances : • Renvoyer des résultats déterminés notamment dans des tests unitaires automatisés • Obtenir un état difficilement reproductible (erreur d'accès réseau, ...) • Eviter d'invoquer des ressources longues à répondre (accès à une base de données, ...) • Invoquer un composant qui n'existe encore pas • Les objets de type mock sont donc très intéressants pour simuler le comportement de composants invoqués de façon distante (exemple : EJB, services web, RMI, ...) et particulièrement pour tester les cas d'erreurs (problème de communication, défaillance du composant ou du serveur qui gère leur cycle de vie, ...).

  8. Utilisation dans les tests unitaires • Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée.

  9. Utilisation dans les tests d’intégration • Les objets mock sont particulièrement utiles dans les tests unitaires mais ils sont à éviter dans les tests d'intégration. Le but des tests d'intégration étant de tester les interactions entre les modules et les composants, il n'est pas forcement souhaitable de simuler le comportement de certains d'entre eux. • Pour les tests d'intégration, les objets mock peuvent cependant être utiles dans certaines circonstances : • Pour simuler un module dont le temps de traitement est particulièrement long • Pour simuler un module qui est complexe à initialiser • Pour simuler des cas d'erreurs

  10. Simulation de l’appel à des ressources • Les tests unitaires doivent toujours s'exécuter le plus rapidement possible notamment si ceux-ci sont intégrés dans un processus de build automatique. Un test unitaire ne doit donc pas utiliser de ressources externes comme une base de données, des fichiers, des services, ... Les tests avec ces ressources doivent être faits dans les tests d'intégration puisque se sont des dépendances.

  11. La simulation du comportement de composants ayant des résultats variables • Les tests utilisant une fonctionnalité dont le résultat est aléatoire ou fluctuant selon les appels avec le même contexte ne sont pas répétables. • Exemple : une méthode qui convertit le montant d'une monnaie dans une autre. La méthode utilise un service web pour obtenir le cours de la monnaie cible. A chaque exécution du cas de test, le résultat peut varier puisque le cours d'une monnaie fluctu. • Pour permettre d'exécuter correctement les tests d'une méthode qui utilise une telle fonctionnalité, il faut simuler le comportement du service dépendant pour qu'il retourne des valeurs prédéfinies selon le contexte fourni en paramètre. Ainsi pour chaque cas de tests, le service retournera la même valeur rendant ainsi les résultats prédictibles et donc les tests répétables.

  12. La simulation des cas d’erreurs • Certaines erreurs sont difficiles à reproduire donc à tester, par exemple un problème de communication avec le réseau, d'accès à une ressource, de connexion à un serveur (Base de données, Broker de messages, système de fichiers partagés,...). • Il est possible d'effectuer des opérations manuelles pour réaliser ces tests (débrancher le câble réseau, arrêter un serveur, ...) mais ces opérations sont fastidieuses et peux automatisables. • Il est par contre très facile pour un objet Mock de retourner une exception qui va permettre de simuler et de tester le cas d'erreur correspondant.

  13. Framework • L'écriture d'objets de type mock à la main peut être long et fastidieux et peut contenir comme toute portion de code des bugs. Pour faciliter leur mise en œuvre, des frameworks ont été créés pour permettre de créer dynamiquement des objets mock de façon fiable. • La plupart des frameworks de mocking permettent de spécifier le comportement que doit avoir l'objet mock : • les méthodes invoquées : paramètres d'appels et valeur de retour • l'ordre d'invocations de ces méthodes • le nombre d'invocations de ces méthodes

  14. Inconvénients La génération d'objets mock n'est pas toujours pratique car cela permet de créer ses objets mais ceux-ci doivent être maintenus au fur et à mesure des évolutions du code à tests. L'inconvénient c'est que le code du test unitaire devient plus important, donc plus complexe donc plus difficile à maintenir. La plupart des frameworks permettent de préciser et de vérifier l'ordre et le nombre d'appels des méthodes mockées qui sont invoquées lors des tests. Si un refactoring est appliqué sur ces méthodes changeant leur ordre d'invocation, le test devra être adapté en conséquence. La mise en œuvre d'objets de type mock doit tenir des limites de leur utilisation. Par exemple, elle masque complètement les problèmes d'interactions entre des dépendances => tests unitaires sont nécessaires mais pas suffisant.

More Related