Mockito método de re-talón ya se apagó con thenthrow
Pregunta
me encontré con un problema con Mockito.
Estoy desarrollando una aplicación web. En las pruebas que se burló de la gestión de usuarios.
Hay algunos casos en que tengo que alterar el usuario devuelve el método getLoggedInUser()
.
El problema es que mi método getLoggedInUser()
también puede lanzar una AuthenticationException
.
Así que cuando trato de cambiar de ningún usuario a algún usuario, la llamada a
when(userProvider.getLoggedInUser()).thenReturn(user);
lanza una excepción, ya que userProvider.getLoggedInUser()
ya se apagó con thenTrow()
¿Hay alguna manera de decirle al método when
no a la atención acerca de las excepciones?
Gracias de antemano - István
Solución
Mi primera reacción a su pregunta es que parece que usted está tratando de hacer demasiado en una sola prueba.
Para facilitar la prueba y la sencillez de cada prueba debe probar una sola cosa. Esta es la misma que la Individual Responsabilidad Principio . A menudo me encuentro programadores que tratan de probar varias cosas en una prueba y que tienen todo tipo de problemas a causa de ella. Así que cada uno de sus métodos de prueba de la unidad debe seguir este flujo:
- Configuración de un solo escenario para la prueba.
- Realizar una llamada a la clase que se está probando para activar el código que está siendo probado.
- Verificar el comportamiento.
Así que en su caso yo esperaría ver al menos dos pruebas. Uno donde getLoggedInUser()
devuelve un usuario, y uno donde getLoggedInUser()
lanza una excepción. De esa manera usted no tendrá problemas con el intento de simular el comportamiento diferente en el simulacro.
El segundo pensó que vienen a la mente no es a trozo. Mira en el uso de esperar en su lugar porque se puede configurar una serie de expectativas. Es decir. la primera llamada devuelve un usuario, la segunda llamada se produce una excepción, la tercera llamada devuelve un usuario diferente, etc.
Otros consejos
En las nuevas versiones Mockito que puede utilizar stubbing llamadas consecutivas a lanzar una excepción en la primera lata y devolver un valor en una segunda llamada.
when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");
¿Hay alguna manera de decirle al método cuando no a la atención acerca de las excepciones?
Para responder a esta pregunta en realidad:
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.mockito.Mockito;
import java.util.ArrayList;
public class MyTest {
@Test
public void testA() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.indexOf(any())).thenReturn(6);
when(list.indexOf(any())).thenReturn(12);
// execute
int index = list.indexOf(new Object());
// verify
assertThat(index, is(equalTo(12)));
}
@Test
public void testB() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
when(list.add(any())).thenReturn(true);
// execute
list.add(new Object());
}
@Test
public void testC() {
// setup
ArrayList<Object> list = mock(ObjectArrayList.class);
when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!"));
Mockito.reset(list);
when(list.add(any())).thenReturn(true);
// execute
list.add(new Object());
}
/**
* Exists to work around the fact that mocking an ArrayList<Object>
* requires a cast, which causes "unchecked" warnings, that can only be suppressed...
*/
class ObjectArrayList extends ArrayList<Object> {
}
}
TestB
falla debido a la aserción de que no puede deshacerse de. TestC
muestra cómo el método reset
se puede utilizar para restablecer la maqueta y quitar el comando thenThrow
en él.
Tenga en cuenta que el restablecimiento no siempre parece funcionar en algunos ejemplos más complicados que tengo. Sospecho que podría ser porque están usando en lugar de PowerMockito.mock
Mockito.mock
?
Parece que usted puede tener que utilizar una respuesta personalizada. Aquí es un ejemplo .