Tests mit Gewinde.schlafen
Was sind die empfohlenen Methoden für die Verwendung Thread.sleep()
zu beschleunigen tests.
Teste ich eine Netzwerk-Bibliothek mit einem retry-Funktionalität, wenn die verbindungen gelöscht oder timeout-Fehler auftreten, etc. Die Bibliothek verwendet jedoch eine Thread.sleep()
zwischen den Wiederholungen (damit es sich nicht verbinden kann Tausende Male während der server neu gestartet wird). Der Aufruf ist eine Verlangsamung der unit-tests deutlich, und ich Frage mich, was die Optionen sind, um es zu überschreiben.
Hinweis, ich bin offen für eigentlich ändern des Codes oder die Verwendung eines mocking framework mock-Thread.sleep(), aber würde gerne hören, Ihre Meinungen/Empfehlung zuerst.
- dies könnte betrachtet werden als casestudy für unit-Tests mit mocking
- Verwenden Sie nicht Thread.sleep(), verwenden Sie eine wait () - Ansatz. Thread.sleep() verwendet CPU-Zyklen, während wait() nicht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es normalerweise eine gute Idee, delegieren, Zeit-bezogene Funktionalität in eine separate Komponente. Enthalten immer die aktuelle Zeit, sowie Verzögerungen wie Thread.sleep(). Auf diese Weise ist es leicht zu ersetzen Sie diese Komponente mit gespielter während der Prüfung, sowie wechseln Sie zu einer anderen Umsetzung.
Machine
Klasse zu abstrahieren, dass alle.Clock
Klasse. Unterstützt die grundlegenden Operationen wieClock.now()
,Clock.freeze()
,Clock.freeze(pointInTime)
und so weiter. Keine Komponente interagiert mit der runtime direkt zu Holen, Zeit, sondern gehen durchClock
.Nur ich Stand vor einer ähnlichen Frage und habe ich eine
Sleeper
Schnittstelle zu abstrahieren, diese Weg:Die default-Implementierung verwendet
Thread.sleep()
:In meine unit-tests, ich Spritzen ein
FixedDateTimeAdvanceSleeper
:Dies ermöglicht es mir, eine Abfrage für eine Zeit in einem unit-test:
Beachten Sie, dass Sie benötigen, um fix die Zeit, zuerst mit
DateTimeUtils.setCurrentMillisFixed( new DateTime( "2014-03-26T09:37:13" ).getMillis() );
zu Beginn Ihrer Prüfung und Wiederherstellung der mal wieder nach dem test mitDateTimeUtils.setCurrentMillisSystem();
Machen die Zeit schläft konfigurierbar über einen setter und einen Standardwert angeben. So in Ihre unit-tests, Aufruf der setter mit einem kleinen Streit (1 Beispiel), und führt dann die Methode aufrufen würde
Thread.sleep()
.Einen anderen, ähnlichen Ansatz zu machen, wenn konfigurierbar über einen booleschen Wert, so dass
Thread.sleep()
ist nicht aufgerufen, wenn derboolean
eingestellt istfalse
.Erstellen einige retry delay-Typ, stellt die Richtlinie für die Wiederholung Verzögerungen. Aufrufen einer bestimmten Methode auf die Richtlinien für die Verzögerung. Mock, wie Sie möchten. Keine bedingte Logik oder
true
/false
flags. Nur Spritzen die Art, die Sie möchten.In ConnectRetryPolicy.java
In SleepConnectRetryPolicy.java
In MockConnectRetryPolicy.java
Ich würde behaupten, warum sind Sie versuchen zu testen, Thread.schlafen. Es scheint mir, du bist versuchen zu testen, das Verhalten als Folge eines Ereignisses.
d.h. was passiert, wenn:
Wenn Sie den Modell-code auf Ereignissen beruhen, dann können Sie testen, was passieren soll, sollte ein bestimmtes Ereignis eingetreten ist, anstatt zu kommen mit ein Konstrukt, dass Masken die concurrent-API-Aufrufe. Was sind Sie wirklich-testen? Sind Sie testen, wie Ihre Anwendung reagiert auf verschiedene Reize oder einfach die Prüfung der JVM korrekt arbeitet?
Ich Stimme mit den anderen Leser, dass es manchmal nützlich, um eine Abstraktion, um beliebigen code Zeit oder den thread bezogen, d.h. Virtuelle Uhr http://c2.com/cgi/wiki?VirtualClock so können Sie mock aus timing - /Auger-Verhalten und konzentrieren sich auf das Verhalten der Einheit selbst.
Es auch klingt, sollten Sie state-Muster, so dass Sie ein Objekt hat bestimmte Verhalten, je nachdem, in welchem Zustand es ist in. ich.e AwaitingConnectionState, ConnectionDroppedState. Übergang zu anderen Staaten wäre über die verschiedenen Ereignisse, d.h. timeout, fallen gelassen etc. Nicht sicher, ob dies zu viel für Ihre Bedürfnisse, aber es ist sicherlich entfernt eine Menge von bedingten Logik-die machen den code komplizierter und unklarer.
Wenn man dieses Weg, dann kannst du immer noch testen Verhaltens auf der unit-Ebene, während noch in der Testphase, die in situ durch eine integration in test oder Abnahme später.
Eugene ist in Ordnung, machen Sie Ihre eigene Komponente zu wickeln das system, das außerhalb Ihrer Kontrolle, Genau dies selbst getan dachte, ich würde teilen, dies ist bekannt als " SelfShunt ' check this out:
Generator
ist eine Klasse, die beim AufrufgetId()
es gibt die aktuelle system Zeit.Machen wir die test-Klasse 'SelfShunt' und werden die SystemTime-Komponente, die Art und Weise haben wir volle Kontrolle von dem, was die Zeit ist.
Wir wickeln Sie die Komponente, die nicht unter unserer Kontrolle.
Dann machen Sie eine Schnittstelle, damit unsere test 'SelfShunt'