2016-03-20 8 views
0

Ich kämpfe versuchen zu verstehen, wie PowerMockito funktioniert.Aufruf Konstruktor mit und ohne Parameter mit PowerMockito

Was ich versuche zu testen, ist eine Methode, die zwei Methoden der gleichen Klasse aufrufen, und auch eine Methode auf einem Joda DateTime Klasse, die, wie Sie wissen, ist eine letzte Klasse, so dass es unmöglich ist, zu verspotten mit Mockito. Deshalb benutze ich (nach stundenlanger Untersuchung) Powermockito.

I @RunWith(PowerMockRunner.class) und @PrepareForTest mit den beiden Klassen bin mit (die getestet wird und die joda.time.DateTime) und meine setUp() sieht ähnlich wie diese

target = new ClassToBeTested(); 
DateTime TODAY = new DateTime(2016, 8, 6, 0, 0, 0, 0); 
PowerMockito.whenNew(DateTime.class).withNoArguments().thenReturn(TODAY); 

Diese vier Zeilen Code Stunden Untersuchung darstellen, Test und Fehler, aber sie funktionierten: innerhalb der Methode von "Ziel", die ich testen muss, wenn ich ein DateTime Objekt ohne Argumente erstellen, damit ich es verwenden kann, um den aktuellen Tag zu kennen, gibt es das TODAY Objekt zurück. Das Problem ist, dass ich innerhalb dieser Methode auch noch ein paar DateTime Objekte erstellen und sie mit Differenzdaten initialisieren muss (die Logik der Methode beinhaltet, diese beiden Daten mit dem aktuellen Tag zu vergleichen und Maßnahmen zu ergreifen), also, ich dachte, dass die Lösung

DateTime TODAY = new DateTime(2017, 8, 17, 0, 0, 0, 0); 
DateTime createdOn = new DateTime(2016, 7, 6, 10, 0, 0, 0); 
DateTime recordedOn = new DateTime(2016, 7, 7, 12, 20, 0, 0); 
PowerMockito.whenNew(DateTime.class).withNoArguments().thenReturn(TODAY); 
PowerMockito.whenNew(DateTime.class).withAnyArguments().thenReturn(createdOn, recordedOn); 

Aber als ich versuchte, sein könnte, erhielt ich createdOn statt TODAY im DateTime Konstruktor ohne Parameter und anschließend die richtige createdOn und recordedOn. Es ist wie, wenn die Linie withAnyArguments ungültig machen die withNoArguments

Sie deutlicher zu zeigen, was ich tun wollte, das ist, wie sieht aus wie das Verfahren (nur der wichtige Teil)

DateTime today = new DateTime(); //To know current day, I was hoping that the withNoArgument take care of this returning TODAY. But it really received createdOn   
DateTime createdOnDay = new DateTime(this.getDateCreated()); it received , createdOnd  
DateTime recordedOnDay = new DateTime(this.getDateRecorded()); 
// It received recordedOn. 

Kann jemand Punkt getestet werden mir was ich falsch mache?

Grüße

+0

Das ist wahrscheinlich, weil jedes Argument auch für kein Argument gültig ist (ich nehme an, nichts ist irgendetwas). Sie könnten wahrscheinlich mit 'withArgument (Date.class)' oder so etwas umgehen. –

+0

Danke. Ich habe es versucht, aber leider funktioniert das nicht. withArgument erhält keinen "Objekttyp" oder etwas, sondern einen bestimmten Wert. – Nisanio

+0

Haben Sie ** ClassToBeTested ** zu '@PrepareForTest' hinzugefügt. Ich meine, die Klasse, die den 'DateTime'-Konstruktor verwendet, sollte auch zur Annotation hinzugefügt werden. –

Antwort

0

Nebenbemerkung: es ist sehr mutlos PowerMockito „mockNew“ zu verwenden, sollten Sie immer, wenn möglich, Umgestalten der im Test befindlichen Code-Tests zu ermöglichen.


mit diesem:

Foo:

package so36119627; 

public class Foo { 

    private final String bar; 

    public Foo(String bar) { 
     this.bar = bar; 
    } 

    public Foo() { 
     this("hello"); 
    } 

    public String getBar() { 
     return bar; 
    } 
} 

Bar:

package so36119627; 

public class Bar { 
    public String bar() { 
     return new Foo().getBar() + "/" + new Foo("world").getBar(); 
    } 
} 

der folgende Test läuft gut und wh tun an Sie wollen:

package so36119627; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Matchers; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import static org.junit.Assert.assertEquals; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Foo.class, Bar.class}) 
public class BarTest { 
    @Test 
    public void test1() throws Exception { 
     assertEquals("hello/world", new Bar().bar()); 
    } 

    @Test 
    public void test2() throws Exception { 
     // do not inline foo1 and foo2, because of powermock 
     final Foo foo1 = new Foo("with arg"); 
     final Foo foo2 = new Foo("no arg"); 
     PowerMockito.whenNew(Foo.class).withArguments(Matchers.anyString()).thenReturn(foo1); 
     PowerMockito.whenNew(Foo.class).withNoArguments().thenReturn(foo2); 

     assertEquals("no arg/with arg", new Bar().bar()); 
    } 
} 
+0

Refactoring Code Whiteout Tests, nicht sehr gute Idee. –

Verwandte Themen