Par exemple j'ai handler:
@Component
public class MyHandler {
@AutoWired
private MyDependency myDependency;
public int someMethod() {
...
return anotherMethod();
}
public int anotherMethod() {...}
}
pour le tester, je veux écrire quelque chose comme ceci:
@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {
@InjectMocks
private MyHandler myHandler;
@Mock
private MyDependency myDependency;
@Test
public void testSomeMethod() {
when(myHandler.anotherMethod()).thenReturn(1);
assertEquals(myHandler.someMethod() == 1);
}
}
Mais il appelle réellement anotherMethod()
chaque fois que j'essaie de me moquer de lui. Que dois-je faire avec myHandler
pour se moquer de ses méthodes?
Tout d'abord, la raison de se moquer des méthodes MyHandler peut être la suivante: nous testons déjà anotherMethod()
et sa logique est complexe, alors pourquoi devons-nous le tester à nouveau (comme une partie de someMethod()
) si nous pouvons simplement verify
l'appeler?
Nous pouvons le faire à travers:
@RunWith(MockitoJUnitRunner.class}
class MyHandlerTest {
@Spy
@InjectMocks
private MyHandler myHandler;
@Mock
private MyDependency myDependency;
@Test
public void testSomeMethod() {
doReturn(1).when(myHandler).anotherMethod();
assertEquals(myHandler.someMethod() == 1);
verify(myHandler, times(1)).anotherMethod();
}
}
Remarque: en cas d'objet 'd'espionnage', nous devons utiliser doReturn
au lieu de thenReturn
(peu d'explication est ici )
Dans votre code, vous ne testez pas du tout MyHandler. Vous ne voulez pas vous moquer de ce que vous testez, vous voulez appeler ses méthodes réelles. Si MyHandler a des dépendances, vous vous en moquez.
Quelque chose comme ça:
public interface MyDependency {
public int otherMethod();
}
public class MyHandler {
@AutoWired
private MyDependency myDependency;
public void someMethod() {
myDependency.otherMethod();
}
}
Et en test:
private MyDependency mockDependency;
private MyHandler realHandler;
@Before
public void setup() {
mockDependency = Mockito.mock(MyDependency.class);
realHandler = new MyHandler();
realhandler.setDependency(mockDependency); //but you might Springify this
}
@Test
public void testSomeMethod() {
//specify behaviour of mock
when(mockDependency.otherMethod()).thenReturn(1);
//really call the method under test
realHandler.someMethod();
}
Le but est vraiment d'appeler la méthode sous test, mais de se moquer de leurs dépendances éventuelles (par exemple, en appelant une autre classe)
Si ces autres classes font partie de votre application, elles auront leurs propres tests unitaires.
NOTEle code ci-dessus pourrait être raccourci avec plus d'annotations, mais je voulais le rendre plus explicite pour des raisons d'explication (et je ne me souviens pas en quoi consistent les annotations :))