2008-10-22 13 views
7

Ich habe die folgende Klasse:Mocking nicht-öffentliche statische Methoden in abstrakten Klassen mit JMockit?

public abstract class AbstractParent { 
    static String method() { 
     return "OriginalOutput"; 
    } 
} 

Ich möchte diese Methode verspotten. Ich entscheide mich für JMockit. So erstelle ich ein Mock-Klasse:

public class MockParent { 
    static String method() { 
     return "MOCK"; 
    } 
} 

Und mein Test-Code sieht wie folgt aus:

public class RealParentTest { 

    @Before 
    public void setUp() throws Exception { 
     Mockit.redefineMethods(AbstractParent.class, MockParent.class); 
    } 


    @Test 
    public void testMethod() { 
     assertEquals(MockParent.method(),AbstractParent.method()); 
    } 

} 

Leider sagt dieser Test, dass AbstractParent returns "OriginalOutput" statt "MOCK". Irgendwelche Ideen warum? Mache ich etwas falsch? Ich habe versucht, meine Scheinklasse als abstrakt zu erklären, ohne Erfolg.

Bearbeiten Beachten Sie, dass das Ausführen der Methode den Test ohne Problem ausführen lässt ... das ist seltsam, weil Sie mit JMockit in der Lage sind, Methoden beliebigen Umfangs zu verspotten.

Antwort Nur die Mock-Methode muss öffentlich sein, Sie können die ursprüngliche Methode beibehalten wie sie ist.

+0

Nur für den passierenden googler..die akzeptierte Antwort ist jetzt veraltet, da Mockit.redefineMethods veraltet ist ... Ich versuche das richtige zu finden. –

Antwort

6

Die Lösung gefunden: Sie müssen nur die Mock-Methode veröffentlichen (die ursprüngliche Methode kann in ihrer ursprünglichen Sichtbarkeit bleiben).

Ich weiß nicht, warum dies funktioniert, während der ursprüngliche Weg nicht funktioniert (jemand, der mehr als willkommen ist, zu klingeln), aber alles, was Sie tun müssen, ist einfach die Scheinklasse im obigen Beispiel zu ändern:

public class MockParent { 
    public static String method() { 
     return "MOCK"; 
    } 
} 
+1

Sie müssen es im MockParent nicht einmal statisch machen. –

+1

jmockit betrachtet nur öffentliche Methoden. Das ermöglicht Ihrer Scheinimplementierung, über interne Methoden zu verfügen, die Methoden in der Quellklasse nicht entsprechen –

+2

Der Grund, warum die Scheinmethode öffentlich sein muss, ist, dass JMockit die verspottete Methode ändert, um die Scheinmethode aufzurufen. Das heißt, ein Aufruf der ursprünglichen Methode wird von der gleichen Methode auf den Schein umgeleitet. Daher muss die Mock-Methode von dem Punkt aus zugänglich sein, an dem der Aufruf eingefügt wird. –

4

anscheinend ist der neue Weg, dies zu tun, ist MockUp<T>

new MockUp<AbstractParent>(){ 
    @Mock String method() { 
     return "MOCK"; 
    } 
}; 

assertEquals("MOCK" AbstractParent.method()); 

eine weitere Alternative offenbar mit so etwas wie MockParent mit einem @MockClass annonation weiterhin zu bedienen ist. Habe das nicht selbst gemacht, da die andere Inline-Version die Aufgabe erledigt.

Ich habe dies in einem Beispiel project on github implementiert.

+0

Das Original 'AbstractParent.method()' ist 'static'. Dieser Weg kann nicht für 'statische' Methoden verwendet werden. –

+3

@Adeel Ich bitte zu unterscheiden https://github.com/gid79/q224721-jmockit-non-public-methods –

+0

Sorry für meine früheren Kommentar, eigentlich habe ich es versucht, aber es hat nicht wirklich funktioniert, dann habe ich das wissen das war wegen etwas ganz anderem. +1 für die Bereitstellung des Beispiels. –