Was sind die empfohlenen Ansätze zur Verwendung von Thread.sleep()
zur Beschleunigung von Tests?
Ich teste eine Netzwerkbibliothek mit einer Wiederholungsfunktion, wenn Verbindungen unterbrochen werden oder Zeitüberschreitungsfehler usw. auftreten. Die Bibliothek verwendet jedoch Thread.sleep()
zwischen den Wiederholungen (sie verbindet sich also nicht tausende Male, wenn der Server neu gestartet wird ). Der Anruf verlangsamt die Komponententests erheblich, und ich frage mich, welche Möglichkeiten es gibt, sie zu überschreiben.
Hinweis: Ich bin offen dafür, den Code tatsächlich zu ändern oder ein spöttisches Framework zu verwenden, um Thread.sleep () vorzuspielen, möchte aber zuerst Ihre Meinung / Empfehlung hören.
Es ist normalerweise eine gute Idee, zeitbezogene Funktionen an eine separate Komponente zu delegieren. Dazu gehören die aktuelle Uhrzeit sowie Verzögerungen wie Thread.sleep (). Auf diese Weise ist es einfach, diese Komponente während des Tests durch Mock zu ersetzen und zu einer anderen Implementierung zu wechseln.
Stellen Sie die Schlafzeit über einen Setter konfigurierbar ein und geben Sie einen Standardwert an. Rufen Sie in Ihrem Komponententest den Setter mit einem kleinen Argument (z. B. 1) auf und führen Sie dann die Methode aus, die Thread.sleep()
aufrufen würde.
Ein anderer ähnlicher Ansatz besteht darin, wenn er über einen booleschen Wert konfigurierbar ist, dass Thread.sleep()
überhaupt nicht aufgerufen wird, wenn boolean
auf false
gesetzt ist.
Erstellen Sie einen Wiederholungsverzögerungstyp, der die Richtlinie für Wiederholungsverzögerungen darstellt. Rufen Sie eine Methode für den Richtlinientyp für die Verzögerung auf. Mock es wie du willst. Keine bedingte Logik oder true
/ false
Flags. Einfach den gewünschten Typ injizieren.
In ConnectRetryPolicy.java
%Vor%In SleepConnectRetryPolicy.java
%Vor%In MockConnectRetryPolicy.java
%Vor% Ich war gerade mit einem ähnlichen Problem konfrontiert und habe ein Interface Sleeper
erstellt, um das wegzusortieren:
Die Standardimplementierung verwendet Thread.sleep()
:
In meinen Unit-Tests injiziere ich ein FixedDateTimeAdvanceSleeper
:
Damit kann ich die Zeit in einem Komponententest abfragen:
%Vor% Beachten Sie, dass Sie die Uhrzeit zuerst mit DateTimeUtils.setCurrentMillisFixed( new DateTime( "2014-03-26T09:37:13" ).getMillis() );
zu Beginn des Tests korrigieren und die Zeit nach dem Test mit DateTimeUtils.setCurrentMillisSystem();
Eugene hat Recht, machen Sie Ihre eigene Komponente, um das System, das außer Ihrer Kontrolle ist, zu wickeln. Das habe ich selbst getan, dachte ich würde es teilen, das ist bekannt als " SelfShunt " check this out:
Generator
ist eine Klasse, die beim Aufruf von getId()
die aktuelle Systemzeit zurückgibt.
Wir machen die Testklasse 'SelfShunt' und werden zur SystemTime-Komponente, auf diese Weise haben wir volle Kontrolle darüber, wie spät es ist.
%Vor%Wir verpacken die Komponente, die nicht unter unserer Kontrolle steht.
%Vor%Dann machen Sie eine Schnittstelle, damit unser Test 'SelfShunt'
kannIch würde argumentieren, warum versuchen Sie Thread.sleep zu testen. Es scheint mir zu sein, dass du versuchst, das Verhalten als Folge eines Ereignisses zu testen.
d. was passiert wenn:
Wenn Sie Code basierend auf Ereignissen modellieren, können Sie testen, was passieren sollte, wenn ein bestimmtes Ereignis eintritt, anstatt ein Konstrukt zu erstellen, das die parallelen API-Aufrufe maskiert. Was tust du wirklich? Testen Sie, wie Ihre Anwendung auf verschiedene Stimuli reagiert oder ob das Testen der JVM korrekt funktioniert?
Ich stimme den anderen Lesern zu, dass es manchmal nützlich ist, eine Abstraktion um irgendeinen Code-Zeit- oder Thread-verwandten Bereich zu legen, zB: Ссылка damit Sie jedes Timing / gleichzeitige Verhalten ausspionieren und sich auf das Verhalten der Einheit konzentrieren können.
Es klingt auch so, als sollten Sie ein Zustandsmuster übernehmen, so dass Ihr Objekt je nach dem Status, in dem es sich befindet, ein bestimmtes Verhalten aufweist. Beispiel: AvaitingConnectionState, ConnectionDroppedState. Der Übergang zu verschiedenen Zuständen würde über die verschiedenen Ereignisse erfolgen, d. H. Zeitüberschreitung, unterbrochene Verbindung usw. Nicht sicher, ob dieses Overkill für Ihre Bedürfnisse ausreicht, aber es entfernt sicherlich eine Menge bedingter Logik, was den Code komplizierter und unklar machen kann.
Wenn Sie auf diese Weise vorgehen, können Sie das Verhalten auf der Ebene der Einheit noch testen, während Sie später noch mit einem Integrationstest oder einem Abnahmetest vor Ort testen.
Tags und Links java unit-testing testing sleep