web-dev-qa-db-fra.com

Puis-je retarder une réponse de méthode stubbed avec Mockito?

J'écris des tests unitaires maintenant. Je dois simuler une méthode à long terme avec Mockito pour tester la gestion du délai d'attente de mon implémentation. Est-ce possible avec Mockito?

Quelque chose comme ça:

when(mockedService.doSomething(a, b)).thenReturn(c).after(5000L);
44
user961548

Vous pouvez simplement mettre le fil en veille pendant le temps désiré. Attention, de telles choses peuvent vraiment ralentir l'exécution de vos tests automatisés. Vous voudrez peut-être isoler ces tests dans une suite séparée.

Cela ressemblerait à ceci: 

when(mock.load("a")).thenAnswer(new Answer<String>() {
   @Override
   public String answer(InvocationOnMock invocation){
     Thread.sleep(5000);
     return "ABCD1234";
   }
});
54
K.L.

J'ai créé un utils pour cela:

import Java.time.Duration;
import Java.util.concurrent.TimeUnit;

import static org.mockito.Mockito.doAnswer;

public class Stubber {

    public static org.mockito.stubbing.Stubber doSleep(Duration timeUnit) {
        return doAnswer(invocationOnMock -> {
            TimeUnit.MILLISECONDS.sleep(timeUnit.toMillis());
            return null;
        });
    }

    public static <E> org.mockito.stubbing.Stubber doSleep(Duration timeUnit, E ret) {
        return doAnswer(invocationOnMock -> {
            TimeUnit.MILLISECONDS.sleep(timeUnit.toMillis());
            return ret;
        });
    }

}

et dans votre cas de test, utilisez simplement:

doSleep(Duration.ofSeconds(3)).when(mock).method(anyObject());
6
Simon Ludwig

Dans mockito 2.8.44, org.mockito.internal.stubbing.answers.AnswersWithDelay est disponible à cette fin. Voici un exemple d'utilisation

 doAnswer( new AnswersWithDelay( 1000,  new Returns("some-return-value")) ).when(myMock).myMockMethod();
4
Viswanath

Bien mieux pour les tests unitaires, c’est de créer une méthode qui appelle la méthode Thread.sleep (long l), puis moque cette méthode. tant que tu veux. Avec cela, vous pouvez effectuer beaucoup de tests en un clin d'œil tout en testant différents scénarios temporels. Avant d’utiliser ceci, mon UnitTest a fonctionné pendant six minutes. Maintenant, c'est moins de 200ms.

public class TimeTools {
public long msSince(long msStart) {
    return ((System.nanoTime() / 1_000_000) - msStart);
}

public long msNow() {
    return (System.nanoTime() / 1_000_000);
}

public Boolean napTime(long msSleep) throws InterruptedException {
    Thread.sleep(msSleep);
    return true;
}
}
-----------------------------------
@Mock
TimeTools Timetools;

@TEST
public void timeTest() {
when(timeTools.msSince(anyLong()))
            .thenReturn(0l)
            .thenReturn(5_500l)
            .thenReturn(11_000l)
            .thenReturn(11_000l)
            .thenReturn(0l)
            .thenReturn(11_000l)
            .thenReturn(11_000l)
            .thenReturn(0l)
            .thenReturn(29_000l);
}

Mais la meilleure approche est d’injecter le sommeil, puis de s’en moquer. Donc, dans vos tests, vous ne dormirez pas réellement. Ensuite, vos tests unitaires se dérouleront à la vitesse de l'éclair.

0
Matej Lachman