1

Ich bin ein Newie in Junit-Tests, aber ich muss etwas Code testen. Ich glaube, ich weiß jetzt, die Grundlagen der es, aber ich habe immer noch ein Problem, an dem ich nichts im Internet finden konnte:Wie mockt man einen statischen Methodenaufruf auf ein Objekt in einer statischen Methode?

Hier ist die Klasse I zu testen wollen:

public static void methodToTest(Label l2, Label l3, User u) { 


    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 


    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
} 

I don‘ Ich möchte, dass das System die Ganzzahlen "first" und "second" erstellt. Stattdessen möchte ich nur, dass sie "1" sind, damit ich testen kann, ob die letzten Codezeilen richtig funktionieren.

MyDB ist eine öffentliche Klasse mit statischen Methoden (irgendeinemethode() und someOtherMethod())

ich die Methode methodToTest testen möchten. Ich habe versucht, diese Methode mit parms zu bezeichnen und am Ende die modifizierten Params mit den erwarteten zu vergleichen.

Ich benutze Mockito und PowerMockito.

Dies ist einer meiner Versuche:

@PrepareForTest({ClassToTest.class, MyDB.class }) 
@RunWith(PowerMockRunner.class) 
public class Test extends PowerMockTestCase{ 
    PowerMockito.mockStatic(MyDB.class); 
    PowerMockito.doReturn(1).when(MyDB.someMethod(u.anotherMethod()).size()); 
    PowerMockito.doReturn(1).when(MyDB.someOtherMethod(u).size()); 
    ClassToTest.methodToTest(l1, l2, u); 
    assertTrue(l1.equals(l3) && l2.equals(l4)); 
} 

Die Ausnahme, die ich erhalte, ist: ‚Argument übergeben, wenn() ist kein Schein!‘

Ich hoffe, dass mir jeder helfen kann. Ich habe so viele Stunden gebraucht, um dieses Problem zu lösen, ohne Erfolg.

Danke !!!

+0

Natürlich könnten Sie die statischen Methoden verspotten, aber wäre es nicht besser, sie loszuwerden und die unbequemen, getunnelten Abhängigkeiten, die sie bringen? Das wäre mein Vorschlag: Vermeiden Sie statische Methoden. Wenn Sie mit dem Code von jemand anderem arbeiten und ihn nicht umgestalten, bis Sie Tests in der Umgebung haben, könnte ein Tool wie JMockit einfacher zu verwenden sein als Mockito und PowerMockito. – unigeek

Antwort

0

Wie ich in meinem Kommentar erwähnt habe, haben Sie festgestellt, dass die statischen Methoden ein Testhindernis darstellen. Also würde ich vorschlagen, dass Sie statische Methoden vermeiden. Lassen Sie uns sehen, was das in Ihrem Beispiel aussehen könnte:

Sie einen Code haben Sie testen müssen ..

public class ProductionClass { 
    public static void methodToTest(Label l2, Label l3, User u) { 
    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 
} 

Erste Dinge, die die statische Methode der Produktion Klasse eine Instanz Methode first..make:

public class ProductionClass { 
    public void methodToTest(Label l2, Label l3, User u) { // removed "static" 
    int first = MyDB.someMethod(u.anotherMethod()).size(); 
    int second = MyDB.someOtherMethod(u).size(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 
} 

Ok, Sie haben also weiterhin eine Kopplung mit statischen Methoden auf MyDB. Wenn Sie diese eine statische Methode loswerden wollten, war Ihre Produktionsklasse viel überprüfbarer. Hier ist how..you kann so ein paar Extrakt Methode Refactoring tun:

public class ProductionClass { 
    public void methodToTest(Label l2, Label l3, User u) { 
    int first = getFirst(); 
    int second = getSecond(); 

    if (first == 1) { 
     l2.setCaption("..."); 
    } 

    ... 
    } 

    int getFirst() { 
    return MyDB.someMethod(u.anotherMethod()).size(); 
    } 

    int getSecond() { 
    return MyDB.someOtherMethod(u).size(); 
    } 
} 

Jetzt können Sie leicht, dass die Produktion Klasse eine Unterklasse und überschreiben (oder partielle Mock, wenn Sie es vorziehen) die Methoden, mit denen Sie futz wollen ..

public class TestableProductionClass extends ProductionClass { 
    @Override 
    int getFirst() { 
    return 1; 
    } 

    @Override 
    int getSecond() { 
    return 1; 
    } 
} 

Wäre es nicht machen es noch schwerer als es braucht dazu neigt, zu sein und PowerMock Einführung Komplexität hinzufügen, die ich lieber nicht beschäftigen. YMMV. Viel Glück!