java - test - mockito spring
Ejemplo sobre el argumento de MockitoCaptor (4)
¿Alguien puede darme un ejemplo que muestre cuál es el uso de la clase
org.mockito.ArgumentCaptor
y cómo es diferente de los
simples matchers
que se proporcionan con mockito.
Leí los documentos simulados proporcionados, pero esos no lo ilustran claramente, ni pueden explicarlo con claridad.
Aquí te estoy dando un ejemplo adecuado de un método de devolución de llamada. así que supongamos que tenemos un método como método login ():
public void login() {
loginService = new LoginService();
loginService.login(loginProvider, new LoginListener() {
@Override
public void onLoginSuccess() {
loginService.getresult(true);
}
@Override
public void onLoginFaliure() {
loginService.getresult(false);
}
});
System.out.print("@@##### get called");
}
También puse aquí toda la clase auxiliar para aclarar el ejemplo: clase loginService
public class LoginService implements Login.getresult{
public void login(LoginProvider loginProvider,LoginListener callback){
String username = loginProvider.getUsername();
String pwd = loginProvider.getPassword();
if(username != null && pwd != null){
callback.onLoginSuccess();
}else{
callback.onLoginFaliure();
}
}
@Override
public void getresult(boolean value) {
System.out.print("login success"+value);
}}
y tenemos oyente LoginListener como:
interface LoginListener {
void onLoginSuccess();
void onLoginFaliure();
}
ahora solo quería probar el método login () de la clase Login
@Test
public void loginTest() throws Exception {
LoginService service = mock(LoginService.class);
LoginProvider provider = mock(LoginProvider.class);
whenNew(LoginProvider.class).withNoArguments().thenReturn(provider);
whenNew(LoginService.class).withNoArguments().thenReturn(service);
when(provider.getPassword()).thenReturn("pwd");
when(provider.getUsername()).thenReturn("username");
login.getLoginDetail("username","password");
verify(provider).setPassword("password");
verify(provider).setUsername("username");
verify(service).login(eq(provider),captor.capture());
LoginListener listener = captor.getValue();
listener.onLoginSuccess();
verify(service).getresult(true);
tampoco olvide agregar anotaciones sobre la clase de prueba como
@RunWith(PowerMockRunner.class)
@PrepareForTest(Login.class)
Estoy de acuerdo con lo que dijo @fge, más terminado. Veamos un ejemplo. Considera que tienes un método:
class A {
public void foo(OtherClass other) {
SomeData data = new SomeData("Some inner data");
other.doSomething(data);
}
}
Ahora, si desea verificar los datos internos, puede usar el captor:
// Create a mock of the OtherClass
OtherClass other = mock(OtherClass.class);
// Run the foo method with the mock
new A().foo(other);
// Capture the argument of the doSomething function
ArgumentCaptor<SomeData> captor = ArgumentCaptor.forClass(SomeData.class);
verify(other, times(1)).doSomething(captor.capture());
// Assert the argument
SomeData actual = captor.getValue();
assertEquals("Some inner data", actual.innerData);
Las dos diferencias principales son:
- cuando captura incluso un solo argumento, puede hacer pruebas mucho más elaboradas sobre este argumento y con un código más obvio;
-
un
ArgumentCaptor
puede capturar más de una vez.
Para ilustrar esto último, digamos que tiene:
final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);
verify(x, times(4)).someMethod(captor.capture()); // for instance
Luego, el captor podrá darle acceso a los 4 argumentos, sobre los cuales puede realizar aserciones por separado.
De hecho, este o cualquier número de argumentos, ya que un
VerificationMode
no se limita a un número fijo de invocaciones;
en cualquier caso, el captor le dará acceso a todos ellos, si lo desea.
Esto también tiene el beneficio de que tales pruebas son (en mi humilde opinión) mucho más fáciles de escribir que tener que implementar sus propios
ArgumentMatcher
, especialmente si combina mockito con afirmar.
Ah, y considere usar TestNG en lugar de JUnit.
Los pasos para hacer una verificación completa son:
Prepara al captor:
ArgumentCaptor<SomeArgumentClass> someArgumentCaptor = ArgumentCaptor.forClass(SomeArgumentClass.class);
verificar que la llamada a dependiente del componente (colaborador del sujeto bajo prueba) veces (1), es el valor predeterminado, por lo que no es necesario agregarlo.
verify(dependentOnComponent, times(1)).send(someArgumentCaptor.capture());
Haz que el argumento pase al colaborador
SomeArgumentClass someArgument = messageCaptor.getValue();
someArgument puede usarse para afirmaciones