La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

MOCK.

Présentations similaires


Présentation au sujet: "MOCK."— Transcription de la présentation:

1 MOCK

2 Définition Simuler le comportement d'un autre objet concret de façon maitrisée. Utilisé pour les tests unitaires Mais elle peut aussi être mise en œuvre lors des développements pour par exemple remplacer un objet qui n'est pas encore écrit. 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. Mock permet de simuler le comportement d'un autre objet concret de façon maitrisée et de vérifier les invocations qui sont faites de cet objet. 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) On peut utiliser des simulacres dans les cas suivants : 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, un test peut avoir besoin de 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 intéragir avec d'autres équipes ou de nouveaux systèmes matériels) Dans cet article, nous allons voir comment utiliser le pattern, d'abord en utilisant un objet créé à cet effet, puis à l'aide d'un Framework de simulacres.

5 Exemple d'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. Dans une application, les classes ont généralement des dépendances entre elles. Ceci est particulièrement vrai dans les applications développées en couches (présentation, service, métier, accès aux données (DAO), ...). L'idée lors de l'exécution d'un test unitaire est de tester la plus petite unité de code possible, soit la méthode et uniquement le code de la méthode. Hors les classes utilisées dans le code de cette méthode font généralement appel à un ou plusieurs autres objets. Le but n'est pas de tester ces objets qui feront eux même l'objet de tests unitaires mais de tester le code de la méthode : le test unitaire doit concerner uniquement la méthode et ne pas tester les dépendances. Il faut donc une solution pour s'assurer que les objets dépendants fournissent les réponses désirées à leur invocation. Cette solution repose sur les objets de type simulacre. Cela suppose que si le code de la méthode fonctionne comme voulu (validée par des tests unitaires) et que les dépendances fonctionnent comme voulu (validées par leurs tests unitaires) alors ils fonctionneront normalement ensembles. Dans un test unitaire, les classes dépendantes ne doivent pas être testées dans les tests unitaires de la classe. Elles doivent être considérées comme testées, sachant que des tests unitaires qui leur sont dédiés doivent exister. Certaines classes doivent aussi être considérées comme testées : c'est notamment le cas des classes du JRE. Il est très important que les tests unitaires ne concernent que le code de la méthode en cours de test. Autrement, il est difficile de trouver un bug qui peut être dans un objet dépendant de niveau -N. Il est alors nécessaire de simuler le fonctionnement des classes dépendantes. Le but d'un objet Mock est de remplacer un autre objet en proposant de forcer les valeurs de retour de ses méthodes selon certains paramètres. Ainsi l'invocation d'un objet de type mock garantie d'avoir les valeurs attendues selon les paramètres fournies.

6 Mise en œuvre des objets de type mock
Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. Un des avantages d'utiliser des objets mock, notamment dans les tests unitaires, est qu'il force le code à être écrit ou adapté via des refactoring pour qu'il respecte une conception qui permettre de rendre le code testable. Généralement, un objet de type mock est une implémentation d'une interface qui se limite généralement à renvoyer des valeurs déterminées en fonction des paramètres reçus. L'interface est parfaitement adaptée puisque l'objet simulé et l'objet mock doivent avoir le même contrat. Un 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. Les objets mock simulent le comportement d'autres objets mais ils sont aussi capables de vérifier les invocations qui sont faites sur le mock : nombres d'invocations, paramètres fournis, ordre d'invocations, ... La mise en oeuvre d'un objet de type mock dans les tests unitaires suit généralement 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é Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. Les objetsde 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, ...) éviter 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. Les tests unitaires automatisés sont une composante très importante du processus de développement et de maintenance d'une application, malgré le fait qu'ils soient fréquemment négligés. Pour permettre de facilement détecter et corriger d'éventuels bugs dans le code testé, il est nécessaire d'isoler ce code en simulant le comportement de ces dépendances. L'utilisation des objets mock est une technique particulièrement puissante pour permettre des tests unitaires sur des classes. Les objets de type mock permettent réellement des tests qui soient unitaires puisque leur résultat est prévisible, si le test échoue, il y a une forte probabilité que l'origine du problème soit dans la méthode en cours de tests. Ceci facilite la résolution du problème puisque celui-ci est isolé uniquement dans le code en cours de tests. Les objets de type mock permettent de s'assurer que l'échec d'un test n'est pas lié à une de ces dépendances sauf si les données retournées par le ou les objets mock sont erronées vis-à-vis du cas de test en échec.

9 Utilisation dans les tests d’intégration
Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. 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'erreur

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
Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. 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. Bien sûre ce type de tests pose comme pré-requis que le service fonctionne correctement mais cela est du ressort des développeurs du service qui doivent eux aussi garantir le bon fonctionnement de leur service ... en utilisant des tests unitaires.

12 La simulation des cas d’erreurs
Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. La simulation des cas d'erreurs Les objets de type mock peuvent aussi permettre de facilement tester 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 Un objet de type doublure permet donc de simuler le comportement d'un autre objet concret de façon maitrisée. 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 oeuvre, 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 Les frameworks de mocking permettent de créer dynamiquement des objets mocks, généralement à partir d'interfaces. Ils proposent fréquemment des fonctionnalités qui vont bien au de là de la simple simulation d'une valeur de retour : - simulation de cas d'erreur en levant des exceptions - validation de l'appel de méthodes - validation de l'ordre de ces appels ...

14 Inconvénients Les inconvénients des objets de type mock
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. Il est préférable d'utiliser un framework qui va créer dynamiquement les objets mock. L'inconvénient c'est que le code du test unitaire devient plus important, donc plus complexe donc plus difficile à maintenir. L'utilisation d'objets de type mock peut coupler les tests unitaires avec l'implémentation des dépendances utilisées. 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 oeuvre d'objets de type mock doit tenir des limites de leur utilisation. Par exemple, elle masque complète les problèmes d'interactions entre des dépendances. C'est pour cette raison que les tests unitaires sont nécessaires mais pas suffisant. Il peut aussi être intéressant de ne pas mocker systématiquement toutes les dépendances.


Télécharger ppt "MOCK."

Présentations similaires


Annonces Google