Puisque la page qui présente la méthode de description de Mockito lors des tests avec JUnit + Mockito est appropriée, je l'ai organisée à ma manière.
Mock
Il est utilisé lorsque vous souhaitez simuler et remplacer toutes les méthodes de l'instance cible. Dans l'état par défaut, pour les objets, les méthodes avec une valeur de retour renverront null. (Dans Collection, c'est une Collection vide, et dans les valeurs primitives, c'est 0 ou faux ...)
Il peut être simulé en ajoutant l'annotation @ Mock
.
De plus, en affectant @ InjectMocks
à l'instance de la classe à tester,
Vous pouvez brancher une instance fictive de «@ Mock» dans une instance d'un membre «@ Inject» dans une instance.
Spy
Utilisez cette option lorsque vous souhaitez remplacer uniquement une méthode spécifique de l'instance cible. Je ne suis pas très doué pour ça. Y a-t-il un cas où vous souhaitez utiliser le getter et d'autres méthodes telles quelles et remplacer une seule méthode?
Il peut être utilisé en ajoutant l'annotation @ Spy
.
Vous devez créer l'instance vous-même.
Il ne peut pas être injecté avec @ InjectMocks
.
Captor
Principalement utilisé pour capturer et valider les valeurs des arguments. Si l'argument est un objet, il ne peut pas être vérifié avec un matcher standard tel que ʻeq`. À ce moment, Captor est efficace.
Lors de la capture d'arguments, définissez une instance de la classe ArgumentCaptor et donnez-lui @ Captor
.
En supposant que vous concevez en utilisant DI, nous résumerons la description de base en utilisant Mockito.
--Réglez le mode de Mockito sur Strict Stubs
.
--Mockito a trois modes: Silent
, Strict
(v2 par défaut) et StrictStubs
.
--Si vous le définissez sur StrictStubs
, il détectera également la discordance d'arguments du simulacre qui devient le stub, alors définissez-le sur le plus strict.
mock (XX.class)
, spy (new XX ())
, ʻArgumentCaptor.forClass (XX.class) `, mais il est plus simple d'écrire en utilisant des annotations.@ InjectMocks
est ajouté. (ne peut pas nouveau)verify
chaque fois qu'il est appelé.
――Si oui, que faire si vous voulez compter le nombre de fois que vous avez été appelé plusieurs fois?you may prefer to use these methods in place of the alternative with when(),
for all of your stubbing calls.
Et cela. ――Personnellement, il est difficile d'apprendre la méthode de description une par une en fonction de la présence ou de l'absence de la valeur de retour et de la différence entre Mock et Spy. Je pense que ce sera compliqué à regarder.
doXX (). When ()
qui peut être utilisé dans toutes les descriptions.
--Cependant, dans le cas où la valeur de retour est modifiée par l'appel décrit plus loin, la description au format when (). ThenReturn ()
est requise.@RunWith (MockitoJUnitRunner.StrictStubs.class)
, ce qui est magique d'utiliser Mockito dans le test.@ Rule
. (Strictness.STRICT_STUBS
)@ InjectMocks
à la variable de la classe à tester.@ Mock
à la variable de la classe que vous voulez moquer.
-Ajoutez simplement les annotations @InjectMocks et @Mock pour créer une instance.import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
...
@RunWith(MockitoJUnitRunner.StrictStubs.class)
public class XXTest{
@InjectMocks
XXInteractor target;
@Mock
IXXRepository repoMock;
...
}
@ Test
.Lorsque la cible du test est la suivante
public class XXInteractor{
@Inject
IXXRepository repository;
XXEntity fetch(String id) throws NotFoundException{
try{
return repository.findBy(id);
}
catch(UseCaseNotFoundException e){
throw new NotFoundException();
}
}
}
Vous pouvez écrire le test suivant.
private static final String ID = "ID";
@Test
public void testFetchSuccess() throws Exception{
//Renvoie une XXEntity normale uniquement lorsqu'un ID est donné en argument.(Sinon, nul)
doReturn(new XXEntity(ID))
.when(repoMock).findBy(eq(ID));
XXEntity result = target.fetch(ID);
assertThat(result.getId(), is(ID));
}
@Test(expected = NotFoundException.class)
public void testFetchFailureWithNotFound() throws Exception{
doThrow(new RepositoryNotFoundException())
.when(repoMock).findBy(eq(ID));
target.fetch(ID);
}
Le modèle de moquerie de base est illustré ci-dessous.
//S'il y a une valeur de retour
doReturn(new XXEntity(ID))
.when(targetMock).fetch(eq(ID));
//S'il n'y a pas de valeur de retour
doNothing().when(targetMock).delete(eq(ID))
doThrow(new XXException()).when(targetMock).fetch(eq(ID))
doThrow(new XXException()).when(targetMock).delete(eq(ID))
//Renvoie la valeur de retour
doReturn(new XXEntity()).when(targetSpy).fetch()
//Lever une exception
doThrow(new XXException()).when(targetSpy).fetch()
doReturn(new XXEntity(ID))
.when(targetMock).fetch(any())
//Cas sans arguments, ou cas où vous souhaitez renvoyer une valeur différente pour chaque appel avec les mêmes arguments
//Ce cas ne peut pas être écrit avec doReturn, alors décrivez-le au format thenReturn.
when(targetMock.getNextKey())
.thenReturn("ID-1") //Premier appel
.thenReturn("ID-2"); //Deuxième appel
//Cas qui renvoient des valeurs différentes pour chaque argument(Définissez chacun normalement)
doReturn(new XXEntity("ID-1")).when(targetMock).fetch(eq("ID-1");
doReturn(new XXEntity("ID-2")).when(targetMock).fetch(eq("ID-2");
Si l'argument est primitif, il ne peut être vérifié qu'avec ʻeq`, mais si l'argument est un objet ou un système de carte de liste, il ne peut pas être vérifié, il doit donc être combiné avec Captor.
Lorsque la cible du test est la suivante
public class XXInteractor{
@Inject
IXXRepository repository;
void update(XXEntity entity){
repository.update(entity);
}
}
Vérifiez comme suit.
private static final String ID = "ID";
@InjectMocks
XXUseCase target;
@Mock
IXXRepository repoMock;
//Définir le capteur
@Captor
ArgumentCaptor<XXEntity> argCaptor;
@Test
public void testUpdateSuccess(){
//Définir une maquette pour capturer les arguments
doNothing().when(repoMock).update(argCaptor.capture());
target.update(ID);
//Valider les arguments capturés
assertThat(argCaptor.getValue().getId(), is(ID));
}
Un cas de moquerie d'une méthode qui implémente quelque chose comme ref
en C # qui utilise une partie de l'argument comme valeur de retour.
Cette définition de méthode n'est pas testable, elle doit donc être essentiellement résolue par une modification de conception,
Si vous voulez vraiment réécrire le contenu de l'instance que vous avez reçue en argument, vous pouvez le faire par la méthode suivante.
doAnswer( invocation -> {
Object[] args = invocation.getArguments();
//En convertissant l'argument dans cette classe, vous pouvez manipuler cette instance.
//Dans ce cas, le deuxième argument est réécrit, donc args[1]
((XXOutputParam) args[1]).setId("ID");
return null; //Null si la valeur de retour est nulle
}).when(useCaseMock).get(any(), any())
Appelez-le à chaque fois avec la méthode @ Before
.
reset(mock);
https://static.javadoc.io/org.mockito/mockito-core/2.23.4/org/mockito/Mockito.html
Recommended Posts