Ich verwende eine Anwendung, die mapreduce2 verwendet, und teste das gleiche mit MRUnit 1.1.0. In einem der Tests prüfe ich den Ausgang eines Reduzierers, der die "aktuelle Systemzeit" in seine Ausgabe eingibt. I.e. Zu der Zeit, zu der der Reduzierer ausgeführt wird, wird der Zeitstempel in context.write()
verwendet, um mit dem Rest des Ausgangs geschrieben zu werden. Nun, obwohl ich die gleiche Methode verwende, um die Systemzeit in der Testmethode als diejenige zu finden, die ich im Reducer verwende, sind die in beiden berechneten Zeiten im Allgemeinen eine Sekunde auseinander, wie 2016-05-31 19:10:02
und 2016-05-31 19:10:01
. Die Ausgabe in den beiden Fällen ist also anders. Beispiel:Eine Ausgabe vor dem Testen mit MRUnit optimieren
test_fe01,2016-05-31 19:10:01
test_fe01,2016-05-31 19:10:02
Dies verursacht einen Assertionsfehler. Ich möchte diesen Unterschied bei den Zeitstempeln ignorieren, so dass die Tests bestanden werden, wenn der Rest der Ausgabe außer dem Zeitstempel übereinstimmt. Ich suche nach einer Möglichkeit, die Methode, die für die Rückgabe der Systemzeit verwendet wird, zu verspotten, so dass ein fest codierter Wert zurückgegeben wird und der Reduzierer und der Test beide diese verspottete Methode während des Tests verwenden. Ist das möglich? Jede Hilfe wird geschätzt.
Mit freundlichen Grüßen
EDIT: Ich habe bereits Mockito Spion-Funktionalität im meinem Test versucht:
MClass mc = Mockito.spy(new MClass());
Mockito.when(mc.getSysTime()).thenReturn("FakeTimestamp");
jedoch ergibt dies einen Fehler Laufzeit:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
Verfahren getSysTime()
ist öffentlich und statisch und Klasse MClass
ist öffentlich und hat keine übergeordneten Klassen.
Klingt wie eine Lösung, aber ist es nicht möglich, dies zu tun, ohne dem Reduzierer einen Code hinzuzufügen? Ich möchte die 'String getSysTime()' Methode, die in meiner Anwendung implementiert ist (und die die aktuelle Systemzeit zurückgibt), in meinem Test vortäuschen, so dass diese Methode einen fest codierten Zeitstempel zurückgibt. –
Sie könnten Ihren Reducer erweitern und diese Methode überschreiben oder vielleicht etwas wie Mockito verwenden, um sich über diese spezifische Methode lustig zu machen: http://stackoverflow.com/questions/14970516/use-mockito-to-mock-some-methods-but-not- andere –
Die Methode ist nicht in meiner Reducer-Klasse und es gibt eine lange Kette von Aufrufen, durch die der Zeitstempel zurückgegeben wird. Die Frage, die ich gestellt habe, hat viele Abstraktionen und Vereinfachungen. Die Konfigurationslösung würde auch erfordern, dass ich ein Konfigurationsobjekt der Parameterliste aller an der Kette beteiligten Methoden hinzufüge. Die Lösung könnte funktionieren, würde aber eine Menge unerwünschter Komplexitäten und Rückschritte verursachen. Eine ideale Lösung in meinem Fall wäre es, eine bestimmte Methode dieser einen bestimmten Klasse in meinem Test zu verspotten, aber ich bin mir nicht sicher, wie es zu erreichen ist. –