estoy a favor de la solución de Eran Harel y en los casos que no sea posible, la sugerencia de Tomasz Nurkiewicz por espionaje es excelente. Sin embargo, vale la pena señalar que hay situaciones en las que ninguno se aplicaría. P.ej. si el método login
era un poco "más robusto":
public class TestedClass {
public LoginContext login(String user, String password) {
LoginContext lc = new LoginContext("login", callbackHandler);
lc.doThis();
lc.doThat();
}
}
... y esto era viejo código que no pudo ser rediseñado para extraer la inicialización de una nueva LoginContext
a su propio método y aplicar una de las soluciones mencionadas anteriormente .
Para mayor completitud, vale la pena mencionar una tercera técnica: usar PowerMock para inyectar el objeto simulado cuando se llama al operador new
. Sin embargo, PowerMock no es una bala de plata. Funciona aplicando manipulación de código byte en las clases en las que se burla, lo que podría ser una práctica dudosa si las clases probadas emplean manipulación o reflexión de código de bytes y, al menos desde mi experiencia personal, se ha sabido que introducen un impacto de rendimiento en la prueba.Por otra parte, si no hay otras opciones, la única opción que tiene que ser la buena opción:
@RunWith(PowerMockRunner.class)
@PrepareForTest(TestedClass.class)
public class TestedClassTest {
@Test
public void testLogin() {
LoginContext lcMock = mock(LoginContext.class);
whenNew(LoginContext.class).withArguments(anyString(), anyString()).thenReturn(lcMock);
TestedClass tc = new TestedClass();
tc.login ("something", "something else");
// test the login's logic
}
}
Esto era exactamente lo que estaba buscando, gracias Tomasz. La parte extra en la parte inferior del doco sobre doReturn fue especialmente útil. – bwobbones
ninguna alternativa para las versiones menos de 1,8 – pseudoCoder
Sí, el uso de una fábrica que puede ser burlado es la respuesta real aquí. Usar spy es controvertido y evitar IMO. – dhaag23