Quel est le meilleur cadre pour créer des objets fictifs en Java? Pourquoi? Quels sont les avantages et les inconvénients de chaque cadre?
Quel est le meilleur cadre pour créer des objets fictifs en Java? Pourquoi? Quels sont les avantages et les inconvénients de chaque cadre?
Réponses:
J'ai eu beaucoup de succès avec Mockito .
Quand j'ai essayé d'apprendre à propos de JMock et EasyMock, j'ai trouvé que la courbe d'apprentissage était un peu raide (bien que ce soit peut-être juste moi).
J'aime Mockito en raison de sa syntaxe simple et propre que j'ai pu saisir assez rapidement. La syntaxe minimale est conçue pour prendre en charge très bien les cas courants, bien que les quelques fois où j'ai dû faire quelque chose de plus compliqué, j'ai trouvé que ce que je voulais était pris en charge et facile à saisir.
Voici un exemple (abrégé) de la page d'accueil de Mockito:
import static org.mockito.Mockito.*;
List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();
Cela ne devient pas beaucoup plus simple que cela.
Le seul inconvénient majeur auquel je peux penser est qu'il ne se moquera pas des méthodes statiques.
Je suis le créateur de PowerMock donc évidemment je dois le recommander! :-)
PowerMock étend à la fois EasyMock et Mockito avec la possibilité de se moquer des méthodes statiques, des méthodes finales et même privées. Le support EasyMock est complet, mais le plugin Mockito a besoin de plus de travail. Nous prévoyons également d'ajouter le support JMock.
PowerMock n'est pas destiné à remplacer d'autres frameworks, il peut plutôt être utilisé dans les situations délicates lorsque d'autres frameworks ne permettent pas de se moquer. PowerMock contient également d'autres fonctionnalités utiles telles que la suppression des initialiseurs et constructeurs statiques .
Le site du projet JMockit contient de nombreuses informations comparatives pour les kits d'outils de moquerie actuels.
En particulier, consultez la matrice de comparaison des fonctionnalités , qui couvre EasyMock, jMock, Mockito, Unitils Mock, PowerMock et bien sûr JMockit. J'essaie autant que possible de le garder exact et à jour.
J'ai eu du succès avec JMockit .
C'est assez nouveau, et c'est donc un peu brut et sous-documenté. Il utilise ASM pour redéfinir dynamiquement le bytecode de classe, de sorte qu'il peut simuler toutes les méthodes, y compris les constructeurs statiques, privés, et les initialiseurs statiques. Par exemple:
import mockit.Mockit;
...
Mockit.redefineMethods(MyClassWithStaticInit.class,
MyReplacementClass.class);
...
class MyReplacementClass {
public void $init() {...} // replace default constructor
public static void $clinit{...} // replace static initializer
public static void myStatic{...} // replace static method
// etc...
}
Il dispose d'une interface Attentes permettant également des scénarios d'enregistrement / lecture:
import mockit.Expectations;
import org.testng.annotations.Test;
public class ExpecationsTest {
private MyClass obj;
@Test
public void testFoo() {
new Expectations(true) {
MyClass c;
{
obj = c;
invokeReturning(c.getFoo("foo", false), "bas");
}
};
assert "bas".equals(obj.getFoo("foo", false));
Expectations.assertSatisfied();
}
public static class MyClass {
public String getFoo(String str, boolean bool) {
if (bool) {
return "foo";
} else {
return "bar";
}
}
}
}
L'inconvénient est qu'il nécessite Java 5/6.
Vous pouvez également consulter les tests à l'aide de Groovy. Dans Groovy, vous pouvez facilement vous moquer des interfaces Java en utilisant l'opérateur 'as':
def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest
En dehors de cette fonctionnalité de base, Groovy offre beaucoup plus sur le front moqueur, y compris les puissants MockFor
et les StubFor
classes.
J'ai commencé à utiliser des simulacres avec EasyMock . Assez facile à comprendre, mais l'étape de relecture était un peu ennuyeuse. Mockito supprime cela, a également une syntaxe plus propre car il semble que la lisibilité était l'un de ses principaux objectifs. Je ne saurais trop insister sur l'importance de cela, car la plupart des développeurs passeront leur temps à lire et à maintenir le code existant, pas à le créer.
Une autre bonne chose est que les interfaces et les classes d'implémentation sont gérées de la même manière, contrairement à EasyMock où vous devez toujours vous souvenir (et vérifier) d'utiliser une extension de classe EasyMock.
J'ai jeté un rapide coup d'œil à JMockit récemment, et bien que la liste des fonctionnalités de blanchisserie soit assez complète, je pense que le prix de cela est la lisibilité du code résultant, et devoir écrire plus.
Pour moi, Mockito frappe le bon pied, étant facile à écrire et à lire, et traitant la majorité des situations que la plupart des codes nécessiteront. Utiliser Mockito avec PowerMock serait mon choix.
Une chose à considérer est que l'outil que vous choisiriez si vous développiez vous-même ou dans une petite équipe soudée, pourrait ne pas être le meilleur à obtenir pour une grande entreprise avec des développeurs de niveaux de compétences différents. La lisibilité, la facilité d'utilisation et la simplicité nécessiteraient plus d'attention dans ce dernier cas. Cela n'a aucun sens d'obtenir le cadre de simulation ultime si beaucoup de gens finissent par ne pas l'utiliser ou ne pas maintenir les tests.
Nous utilisons beaucoup EasyMock et EasyMock Class Extension au travail et nous en sommes très satisfaits. Il vous donne essentiellement tout ce dont vous avez besoin. Jetez un œil à la documentation, il y a un très bel exemple qui vous montre toutes les fonctionnalités d'EasyMock.
J'ai utilisé JMock tôt. J'ai essayé Mockito lors de mon dernier projet et j'ai bien aimé. Plus concis, plus propre. PowerMock couvre tous les besoins qui sont absents dans Mockito, comme se moquer d'un code statique, se moquer d'une création d'instance, se moquer des classes et méthodes finales. J'ai donc tout ce dont j'ai besoin pour effectuer mon travail.
J'aime JMock parce que vous êtes capable de définir des attentes. C'est totalement différent de vérifier si une méthode a été appelée trouvée dans certaines bibliothèques fictives. En utilisant JMock, vous pouvez écrire des attentes très sophistiquées. Voir le cheat-sheat jmock .
Oui, Mockito est un excellent cadre. Je l'utilise avec hamcrest et Google guice pour configurer mes tests.
La meilleure solution pour se moquer est de faire effectuer tout le travail à la machine avec des tests automatisés basés sur les spécifications. Pour Java, voir ScalaCheck et le cadre Reductio inclus dans la bibliothèque Java fonctionnelle . Avec les frameworks de test basés sur des spécifications automatisées, vous fournissez une spécification de la méthode testée (une propriété qui devrait être vraie) et le framework génère automatiquement des tests ainsi que des objets fantaisie.
Par exemple, la propriété suivante teste la méthode Math.sqrt pour voir si la racine carrée d'un nombre positif n au carré est égale à n.
val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }
Lorsque vous appelez propSqrt.check()
, ScalaCheck génère des centaines d'entiers et vérifie votre propriété pour chacun, s'assurant également automatiquement que les cas de bord sont bien couverts.
Même si ScalaCheck est écrit en Scala et nécessite le compilateur Scala, il est facile de tester le code Java avec. Le framework Reductio en Java fonctionnel est une implémentation Java pure des mêmes concepts.
Mockito fournit également l'option de méthodes de stubbing, de correspondances d'arguments (comme anyInt () et anyString ()), de vérification du nombre d'appels (times (3), atLeastOnce (), never ()), et plus encore .
J'ai également trouvé que Mockito est simple et propre .
Une chose que je n'aime pas chez Mockito, c'est que vous ne pouvez pas bloquer les méthodes statiques .
Pour quelque chose d'un peu différent, vous pouvez utiliser JRuby et Mocha qui sont combinés dans JtestR pour écrire des tests pour votre code Java en Ruby expressif et succinct. Il y a quelques exemples de moquerie utiles avec JtestR ici . Un avantage de cette approche est que se moquer des classes concrètes est très simple.
J'ai commencé à utiliser des simulations via JMock, mais j'ai fini par passer à EasyMock. EasyMock n'était que cela, - plus facile - et offrait une syntaxe plus naturelle. Je n'ai pas changé depuis.