Wie werden Unit-Tests mit einer Methode durchgeführt, die die verstrichene Zeit berücksichtigt?

8

Ich bin gerade dabei, eine wichtige Methode in einem Legacy-System umzugestalten. Es gab fast keinen Test, bis ich anfing, daran zu arbeiten, und ich habe ziemlich viel hinzugefügt, um die korrekte Arbeit nach meinen Umgestaltungen sicherzustellen.

Jetzt bin ich auf den wichtigsten Teil gestoßen: den Algorithmus, der einen Indikator berechnet. Es ist so etwas wie

indicator = (OneNumberFromA + AnotherNumberFromB) / elapsedTime;

Wie kann ich das richtige Verhalten für diese Funktion mit Unit-Tests testen?

Es gibt auch einige leicht unterschiedliche Algorithmen in den Funktionen, die das Programm in einigen Fällen erreicht - aber in allen von ihnen ist das elapsedTimeentscheidend für das Ergebnis.

mhr
quelle

Antworten:

11

So lösen Sie fast jedes Problem mit Unit-Tests: Sie verspotten die verstrichene Zeit.

Ich empfehle, eine standardisierte Methode zu verwenden, um die Systemzeit im gesamten System zu ermitteln und diese Methode dann überschreibbar zu machen, damit Ihre Komponententests die vollständige Kontrolle haben. Die Tests enthalten dann viele raffinierte Anrufe wie Time.fake(timeA)oder sogar Time.stop().

Kilian Foth
quelle
Die Zeit wird tatsächlich über das System abgerufen. Die Funktionsmethode speichert die loginTime und berechnet die verstrichene Zeit über DateTime.Now - loginTime. Ich werde versuchen, das zu verspotten. Danke, dass du mich in diese Richtung gelenkt hast.
mhr
5
Refactor es dann und ersetzen Sie jeden Aufruf von System.currentTimeMillis()durch eine Methode Time.now(), die normalerweise das gleiche tut, aber im Test kann gemacht werden, um einen beliebigen Wert zurückzugeben. Dies kann einige Anstrengungen erfordern, aber es ist unwahrscheinlich, dass etwas kaputt geht, da es sich um eine sehr konzentrierte und in sich geschlossene Änderung handelt.
Kilian Foth
1

Zeitmessung und Indikatorauswertung sollten in verschiedenen Funktionen erfolgen. In Ihrem Fall elapsedTimesollte eine Eingabe der Bewertungsfunktion sein. Auf diese Weise kann Ihr Evaluierungscode getestet werden und ist leichter zu verstehen.

Jetzt haben Sie immer noch das Problem, die Zeitmessfunktion zu testen, aber dies geht über den Rahmen dieser Frage hinaus.

Simon Bergot
quelle
Das ist eines der Dinge, auf die ich zusteuern werde, aber im Moment wird elapsedTime innerhalb der Funktion berechnet . Ich bin mir nicht sicher, ob es gut ist, dies zu extrahieren, ohne einen Test zu haben, um sicherzustellen, dass das beobachtbare Verhalten gleich bleibt - was für Fowlers Refactoring entscheidend ist .
mhr