2016-08-05 12 views
1

Ich habe mich für diese Frage ein wenig umgesehen und habe nicht genau gefunden, was ich brauche. Ich habe ein bisschen mehr über JMockit und Spott gelernt. Was gut ist. Scheint so, als ob jeder wissen möchte, wie man sicherstellt, dass etwas ausgeführt wurde. Ich möchte das Gegenteil erfahren.Überprüfen Sie, dass eine private Methode wurde nicht ausgeführt JMockit

Ok - Ich schreibe einen Test, um einen nicht so glücklichen Pfad in einer öffentlichen Methode zu überprüfen. Die Methode, die getestet wird, ist void, so kann ich nicht wirklich assert die Ergebnisse. Was ich tun möchte, ist zu verifizieren, dass eine Methode in diesem Testfall NICHT ausgeführt wurde.

Zum Beispiel:

class ClassToTest { 
    private void method(String arg){} 

    public void publicMethod(String arg0, String arg1){ 
    if(false){ 
     //this method should never get called. 
     method(arg0); 
    } 
    } 
} 

class TestingClass{ 
    @Tested 
    private ClassToTest classToTest = new ClassToTest(); 

    @Test 
    public void testCheckingIfPrivateMethodWasCalled(){ 
    classToTest.publicMethod("string1", "string2"); 

    new Verifications() { 
     { 
     //At this point I am trying something like 
     Deencapsulation.invoke(classToTest, "method", "string1"); 
     times = 0; //Also tried maxTimes = 0; 
     //Through debug it looks like the invoke is doing what it's named... 
     //invoking the private method, I don't want to invoke. 
     //How do I check that ClassToTest#method was not called? 
     } 
    } 
    } 
} 

Was ich als Ergebnisse für den Testfall immer ein java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter. Welches ist auf der Linie times = 0;.

Ich weiß, dass die invoke die private Methode ausführt. Ich kratze mir am Kopf und versuche herauszufinden, wie man "checkt", dass diese Methode aufgerufen wird, ohne sie aufzurufen/auszuführen.

Danke.

+2

Testen Sie den Zustand Ihrer Anwendung. Wenn der Aufruf Ihrer privaten Methode wichtig ist, sollte sich der Status irgendwo geändert haben, und Sie sollten in der Lage sein, danach zu suchen. Wenn Sie das nicht berücksichtigen, sollten Sie eventuell die Standardsichtbarkeit der Methode angeben (auch als paketgeschützt bezeichnet), damit Ihr Test dies überprüfen kann. (Das geht davon aus, dass Ihr Test im gleichen Paket wie die Klasse, die Sie testen, lebt, was eine vernünftige Annahme ist.) – nasukkin

+0

* Niemals eine private Methode verspotten, es gibt einfach keinen guten Grund, dies zu tun. Denken Sie einmal darüber nach: Private Methoden können jederzeit von Entwicklern, die Wert auf Qualität legen, erstellt oder eingezeichnet werden. Wollen Sie Arbeitstests wirklich modifizieren, während Sie den Produktionscode durch funktionserhaltende Refactorings verbessern? Auch wenn Sie sich nicht darum kümmern, sollten Sie bedenken, dass andere Entwickler im Team oder in der Zukunft könnten. –

Antwort

0

Eine Möglichkeit, es zu tun, ist mit dem MockUp API für faking:

import static org.junit.Assert.assertFalse; 

import org.junit.Test; 

import mockit.Mock; 
import mockit.MockUp; 
import mockit.Tested; 

public class TestingClass { 

    @Tested 
    private ClassToTest classToTest = new ClassToTest(); 

    @Test 
    public void testCheckingIfPrivateMethodWasCalled() { 
     PrivateMethodCheckMockUp mockUp = new PrivateMethodCheckMockUp() { 
      @Mock 
      private void method(String arg) { 
       calledPrivate = true; 
      } 
     }; 

     classToTest.publicMethod("string1", "string2"); 

     assertFalse(mockUp.calledPrivate); 
    } 

    class PrivateMethodCheckMockUp extends MockUp<ClassToTest> { 
     boolean calledPrivate = false; 

     @Mock 
     private void method(String arg) { 
      calledPrivate = true; 
     } 
    } 
} 
+0

Sie verspotten also eine Instanz der Klasse und verspotten dann die Methode für diese Klasse? Was machst du zweimal "PrivateMethodCheckMockUp # Methode"? –

+0

Eigentlich wird 'ClassToTest' nur einmal gespottet,' @Tested' erzeugt keinen Mock, "JMockit kann helfen, indem er diese Klasse automatisch instanziiert und optional die relevanten mokierten Abhängigkeiten einfügt. Dafür ist die @Tested-Annotation gedacht." – Alfergon

+0

Dann mache ich seine private Methode mit der 'MockUp'-API und benutze eine Flagge, um zu wissen, ob sie aufgerufen wurde oder nicht (vielleicht mit' Assert.fail() 'hätte es genügt). – Alfergon

Verwandte Themen