J'ai commencé à utiliser Guice pour effectuer des injections de dépendances sur un projet, principalement parce que j'ai besoin d'injecter des couches (en utilisant JMock actuellement) à une couche du test unitaire, ce qui rend l'injection manuelle très difficile.Quelle est la meilleure façon d'utiliser Guice et JMock ensemble?
Ma question est quelle est la meilleure approche pour introduire un simulacre? Ce que j'ai actuellement est de faire un nouveau module dans le test unitaire qui satisfait les dépendances et les lier avec un fournisseur qui ressemble à ceci:
public class JMockProvider<T> implements Provider<T> {
private T mock;
public JMockProvider(T mock) {
this.mock = mock;
}
public T get() {
return mock;
}
}
En passant la maquette dans le constructeur, donc une configuration JMock pourrait ressembler ceci:
final CommunicationQueue queue = context.mock(CommunicationQueue.class);
final TransactionRollBack trans = context.mock(TransactionRollBack.class);
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(CommunicationQueue.class).toProvider(new JMockProvider<QuickBooksCommunicationQueue>(queue));
bind(TransactionRollBack.class).toProvider(new JMockProvider<TransactionRollBack>(trans));
}
});
context.checking(new Expectations() {{
oneOf(queue).retrieve(with(any(int.class)));
will(returnValue(null));
never(trans);
}});
injector.getInstance(RunResponse.class).processResponseImpl(-1);
Y a-t-il un meilleur moyen? Je sais qu'AtUnit essaye de résoudre ce problème, bien qu'il me manque comment il injecte magiquement un faux qui a été créé localement comme ci-dessus, mais je cherche une raison convaincante pourquoi AtUnit est la bonne réponse ici (autre que sa capacité à changer les cadres DI et moqueurs sans changer les tests) ou s'il y a une meilleure solution pour le faire à la main.
Dans l'exemple spécifique, vous avez raison de dire que DI n'est pas nécessaire pour se moquer (si j'ai rendu le paquet constructeur privé, je suppose), mais d'ici j'ai des dépendances qui doivent être injectées à deux pas du code de test (RunResponse obtient un nom de classe hors de la file et l'instancie), donc je regardais Guice pour faire une injection sur le terrain dans ce but. – Yishai
Je vois. Rien ne vous empêche d'utiliser Guice dans les tests, mais si possible, je suggère d'essayer de l'éviter (sauf si vous testez sur un niveau fonctionnel/d'intégration) Le problème avec cela est que vous violez la loi de Demeter . Votre classe actuelle devrait seulement s'inquiéter de ses dépendances immédiates et les dépendances transitives ne devraient pas être prises en compte. Dans les tests unitaires pour les dépendances de classes actuelles, vous faites exactement la même chose et ne considérez que les dépendances immédiates.Un tel modèle rend votre code plus propre et plus sympathique DI :) – gpampara