## EasyMock Class Extension 2.5 Readme

Documentation de la version 2.5 (2009-12-15)
© 2003-2009 OFFIS, Henri Tremblay.

Documentation traduite originellement de l'anglais par Alexandre de Pellegrin. Maintenue par Henri Tremblay.

EasyMock Class Extension permet de générer des Mock Objects à partir de classes.

## Pré-requis

EasyMock Class Extension nécessite Java 5 ou supérieur, EasyMock 2.5, cglib 2.1 (2.0.x fonctionne également mais ne permet pas de "mocker" une classe sans constructeur visible), asm (utilisez la version appropriée pour votre version de cglib; vous pouvez aussi prendre cglib-nodep-2.1.jar qui inclut asm) et JUnit 4 pour éxécuter les tests.

## Utilisation

Pour générer des Mock Objects de classes et d'interfaces, utilisez

    import static org.easymock.classextension.EasyMock.*;

au lieu de

    import static org.easymock.EasyMock.*;

Vous pourrez ensuite créer un Mock Object, de la même façon qu'avec EasyMock, en faisant quelque chose comme:

    ToMock mock = createMock(ToMock.class);

A partir de là, vous pouvez utiliser votre mock comme vous le faisiez avec EasyMock. Notez que les méthodes `createNiceMock`, `createStrictMock`, `createStrictControl`, `createControl` and `createNiceControl` sont aussi disponibles. Les méthodes `create...Control()` retournent un object de type `org.easymock.classextension.IMocksControl`, une extension de la classe `IMocksControl` d'EasyMock.

## Utilisation avancée

### Mocking partiel

Dans certains cas, vous pouvez avoir besoin de "mocker" uniquement certaines méthodes d'une classe et de conserver un comportement normal pour les autres. Cela arrive habituellement lorsque pour souhaitez tester une méthode appelant d'autres méthodes de la même classe. Vous voulez donc garder le comportement normal de la méthode testée et "mocker" les autres.

Dans ce cas, la premier réflexe à avoir est d'envisager un refactoring car, bien souvent, ce problème est la conséquence d'un mauvais design. Si ce n'est pas le cas ou si vous ne pouvez faire autrement pour une quelconque contrainte de développement, voici la solution:

    ToMock mock = createMockBuilder(ToMock.class)
       .addMockedMethod("mockedMethod").createMock();

Seules les méthodes ajoutées avec `addMockedMethod(s)` seront "mockées" (`mockedMethod()` dans l'exemple). Les autres conservent leur comportement habituel. Une exception: les méthodes abstraites sont "mockées" par défaut.

`createMockBuilder` retourne l'interface `IMockBuilder`. Elle contient diverses méthodes pour facilement créer un mock partiel. Jettez un coup d'oeil à la javadoc pour en savoir plus.

Remarque: EasyMock fournit un comportement par défault pour les méthodes de la classe Object (equals, hashCode, toString). Toutefois, pour un mock partiel, si ces méthodes ne sont pas mockées explicitement, elles auront leur comportement normal et non celui par défaut d'EasyMock.

### Test interne d'une classe

Il est possible de créer un mock en appelant un constructeur de la classe. Ceci peut être utile lorsqu'une méthode doit être testée mais d'autres dans la même classe "mockées". Pour cela vous devez faire quelque chose comme

    ToMock mock = createMockBuilder(ToMock.class)
       .withConstructor(1, 2, 3); // 1, 2, 3 sont les paramètres passés au constructeur

Voir `ConstructorCalledMockTest` pour un exemple d'utilisation.

### Remplacer l'instantiateur par défaut

Parfois (habituellement à cause d'une JVM non supportée), il est possible que EasyMock CE ne soit pas capable de créer un mock dans votre environnement java. Sous le capot, l'instantiation de classes est implémentée par un pattern "factory". En cas de problème, vous pouvez remplacer l'instantiateur par défaut avec:

- L'ancien `DefaultClassInstantiator` qui fonctionne très bien avec les classes sérializable et sinon tente de deviner quel constructeur appeler et quels paramètres lui passer.
- Votre propre instantiateur. Celui-ci doit implémenter `IClassInstantiator`.

Vous assignez ce nouvel instantiateur à l'aide de `ClassInstantiatorFactory.setInstantiator()`. Vous pouvez remettre celui par défaut avec `setDefaultInstantiator()`.

Important: L'instantiateur est gardé statiquement et reste donc entre deux tests. Assurez-vous de le réinitialiser si nécessaire.

### Sérializer une classe mockée

Une class mockée peut aussi être sérializé. Toutefois, comme celle-ci étant une classe sérializable, cette dernière peut avoir un comportement spécial dû à l'implémentation de méthodes tels que `writeObject`. Ces méthodes seront toujours appelées lorsque le mock sera sérializé et peuvent potentiellement échouer. Habituellement, le contournement consiste à créer le mock en appelant un constructeur.

Aussi, il est possible que la dé-sérialization d'un mock ne fonctionne pas si elle est effectuée dans un class loader différent de la sérialization. Ce cas n'a pas été testé.

### OSGi

Le jar d'EasyMock CE jar oeut être utilisé comme bundle OSGi. It exporte les packages `org.easymock.classextension` et `org.easymock.classextension.internal`. Toutefois, pour importer le dernier, il faut spécifier l'attribut `poweruser` à true (`poweruser=true`). cglib est aussi exporté pour permettre aux Mock Objects de fonctionner correctement.

## Limitations

EasyMock Class Extension fournit un comportement par défaut pour `equals()`, `toString()` et `hashCode()`. Cela signifie que vous ne pourrez enregistrer votre propre comportement pour ces méthodes. Cette limitation est cohérente avec ce qu'EasyMock fait. Elle doit être considérée comme une fonctionnalité permettant ne ne pas s'occuper de ces méthodes.

Les méthodes finales ne peuvent pas être "mockées". Si appelées, leur code normal sera exécuté.

L'instantiation des classes est faite par Objenesis. Les JVMs supportées sont listées ici.

Dans la section Utilisation avancée, il a été expliqué comment faire un mock partiel. Une chose importante à savoir est que les méthodes privées ne sont jamais "mockées". De ce fait, si votre méthode tester appelle des méthodes privées, vous devrez les tester dans la foulée puisque vous ne pourrez pas les "mocker".

## Développement

## Auteurs

EasyMock Class Extension est présentement maintenue par Henri Tremblay.

Elle a été initialement développée par Joel Shellman, Chad Woolley et Henri Tremblay dans la section fichiers du of Yahoo!Groups.

Remerciements à ceux qui nous ont fourni retour d'expérience et rustines, incluant Rodrigo Damazio, Bruno Fonseca, Ben Hutchison, et de nombreux autres.

### Notes de mises à jour

Nouveau dans la version 2.5:

- Si EasyMock recoit en paramètre un object qui n'est pas un mock, l'exception retournée n'est emballée correctement
- Un mock d'une exception lance une NPE (2407137)
- Migrer vers Subversion
- Tout construire avec Maven
- Objenesis n'est plus incorporé
- Ajout de l'en-tête OSGi au MANIFEST.MF (2774873)
- Nouvelle interface IMockBuilder pour créer des mocks partiels facilement (2822905, 2788098, 2783949)
- Une class mockée est maintenant sérializable (1963458)

Nouveau dans la version 2.4:

- Ajout des méthodes resetToNice/Default/Strict (1963442)
- Pouvoir rendre un Mock object thread-safe (1895644,1953275)
- Correction pour les méthodes bridge appelant super (merci à Barry Kaplan)
- Droits d'auteur étendus sur 2008

Nouveau dans la version 2.3:

- Documentation française
- Pouvoir appeler un constructeur lors d'un mocking partiel
- Les Mock Objects peuvent maintenant être nommés
- Avoir un varargs pour le paramètre "mockedMethods" du mocking partiel
- Version dans le manifeste du jar
- Objenesis 1.1 pour le support partiel d'Aonix
- Examples migrés vers JUnit 4
- Pom Maven plus complet
- Les méthodes abstraites sont mockées par défaut lors d'un mock partiel

Nouveau dans la version 2.2.2:

- Utiliser le cache cglib. Augmente grandement les performances et diminue le permgen utilisé
- Instantiation des classes avec Objenesis pour une meilleure portabilité
- Possibilité d'utiliser votre propre instantiateur de classes

Nouveau dans la version 2.2.1:

- Varargs pour record(), replay() et reset()

Nouveau dans la version 2.1:

- Tests migrés vers JUnit 4

Nouveau dans la version 2.0:

- Nouvelle implémentation compatible avec EasyMock 2