Comencé a usar Guice para realizar una inyección de dependencia en un proyecto, principalmente porque necesito inyectar simulaciones (usando JMock actualmente) una capa lejos de la prueba de la unidad, lo que hace que la inyección manual sea muy incómoda.¿Cuál es la mejor manera de usar Guice y JMock juntos?
Mi pregunta es ¿cuál es el mejor enfoque para presentar un simulacro? Lo que tengo actualmente es hacer un nuevo módulo en la prueba de unidad que satisface las dependencias y se unen con un proveedor que tiene este aspecto:
public class JMockProvider<T> implements Provider<T> {
private T mock;
public JMockProvider(T mock) {
this.mock = mock;
}
public T get() {
return mock;
}
}
Pasando el simulacro en el constructor, por lo que una instalación JMock podría parecer esto:
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);
¿Hay una manera mejor? Sé que AtUnit intenta solucionar este problema, aunque me falta cómo inyecta automáticamente un simulacro creado localmente como el anterior, pero estoy buscando una razón convincente por la que AtUnit sea la respuesta correcta aquí (otro que su capacidad para cambiar los marcos de DI y de burla sin tener que cambiar las pruebas) o si hay una mejor solución para hacerlo a mano.
En el ejemplo específico, tiene toda la razón que DI no es necesario para burlarse (si hice el paquete constructor privado, supongo), pero desde aquí tengo dependencias que necesitan ser inyectadas a dos pasos del código de prueba (RunResponse obtiene un nombre de clase de la cola y lo ejemplifica), así que estaba mirando a Guice para hacer la inyección de campo para este propósito. – Yishai
Ya veo. Nada le impide usar Guice en las pruebas, pero si es posible, le sugiero que trate de evitarlo (a menos que esté probando en un nivel funcional/de integración) El problema es que está violando la Ley de Demeter . Su clase actual solo debería preocuparse por sus dependencias inmediatas y las dependencias transitivas no deberían tenerse en cuenta. En las pruebas unitarias para las dependencias de las clases actuales, usted hace exactamente lo mismo y solo considera las dependencias inmediatas.Tal patrón hace que su código sea más limpio y más compatible con DI :) – gpampara