2016-12-03 3 views
-1

Ich weiß, ich sollte keine void Methoden wie diese testen, aber ich bin nur testen Mockito.doNothing() ab sofort mit einem einfachen Beispiel.Mockito.doNothing() gibt immer Null Zeiger Ausnahme

Mein Service-Klasse:

@Service 
public class Service{ 
    @Autowired 
    private Consumer<String, String> kafkaConsumer; 

    public void clearSubscribtions(){ 
     kafkaConsumer.unsubscribe(); 
    } 
} 

My Test-Klasse:

@MockBean 
private Consumer<String, String> kafkaConsumer; 

@Test 
public void testClearSubscriptions() { 
    Service service = new Service(); 

    Mockito.doNothing().when(kafkaConsumer).unsubscribe(); 
    service.clearSubscriptions(); 
} 

Der Test hält mit einer Null-Zeiger-Ausnahme fehlschlägt. Wenn ich es debuggte, geht es in die clearSubscription-Methode der Serviceklasse, und dort in der Zeile von kafkaConsumer.unsubscribe() ist kafkaConsumer null. Aber ich habe den Verbraucher verspottet, warum wirft er eine Nullzeiger-Ausnahme und ich sollte diese Methode überspringen, richtig?

Edit: Alle Erklärungen der Klasse:

@Autowired 
    private Consumer<String, String> kafkaConsumer; 

    @Autowired 
    private Service2 service2; 

    private final Object lock = new Object(); 

    private static Logger logger = LoggerFactory.getLogger(Service.class); 

    private HashMap<String, String> subscribedTopics = new HashMap<>(); 

herausgefunden, was falsch war, ich Auto Draht

den Dienst benötigt
+0

Weil ich davon ausgehen, mit mockbean Annotation des Federverschlusses, dass das Feld nicht verspottet zu verspotten ist. Du scheinst Spring und Mockito zu mischen. Können Sie alle Deklarationen der Klasse anzeigen? Ich denke, dass das Problem da ist. – davidxxx

Antwort

1

Sie einen neuen Service Service service = new Service(); Instanziieren aber von dem, was ich kann, Sie sehen, dass Sie die Mock Bean niemals in den neuen Service injizieren. Hier

ist ein Beispiel dessen, was ich denke, Sie tun können, wenn Sie Mockito verwenden nur und brauchen nicht einen Federbehälter zu instanziiert (eine einzige Klasse für eine einfache Beispiel verwendet nicht dies in eigentlichen Code):

package com.sbp; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.InjectMocks; 
import org.mockito.Mock; 
import org.mockito.Mockito; 
import org.mockito.runners.MockitoJUnitRunner; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 

@RunWith(MockitoJUnitRunner.class) // run with mockitos runner so annotations are processed 
public class MyServiceTest { 

    public interface Consumer<T, R> { 

     public void unsubscribe(); 
    } 

    @Service 
    public class KafkaConsumer implements Consumer<String, String> { 

     @Override 
     public void unsubscribe() { 
     } 

    } 

    @Service 
    public class MyService { 

     @Autowired 
     private Consumer<String, String> kafkaConsumer; 

     public void clearSubscriptions() { 
      kafkaConsumer.unsubscribe(); 
     } 
    } 

    @Mock // tell mockito that this is a mock class - it will instantiate for you 
    private Consumer<String, String> kafkaConsumer; 

    @InjectMocks // tell mockito to inject the above mock into the class under test 
    private MyService service = new MyService(); 

    @Test 
    public void testClearSubscriptions() { 
     service.clearSubscriptions(); 
     Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe(); 
    } 
} 

Wenn Sie ein Beispiel über Spring mit MockBean oder ohne und Abhängigkeiten benötigen, lassen Sie es mich wissen und ich kann posten.

AKTUALISIERT: Hinzufügen von Proben Feder junit Läufer mit und

package com.sbp; 

import com.sbp.MyServiceTest.TestContext.MyService; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.boot.test.mock.mockito.MockBean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.stereotype.Service; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) // run with spring 
@SpringBootTest(classes = MyServiceTest.TestContext.class) // make it a spring boot test so @MockBean annotation is processed, provide a dummy test context class 
public class MyServiceTest { 

    public interface Consumer<T, R> { 

     public void unsubscribe(); 
    } 

    @Configuration 
    public static class TestContext { 
     @Service 
     public class KafkaConsumer implements Consumer<String, String> { 

      @Override 
      public void unsubscribe() { 
      } 

     } 

     @Service 
     public class MyService { 

      @Autowired 
      private Consumer<String, String> kafkaConsumer; 

      public void clearSubscriptions() { 
       kafkaConsumer.unsubscribe(); 
      } 
     } 
    } 

    @MockBean // this will create a mockito bean and put it in the application context in place of the Kafka consumer bean defined in the TestContext class 
    private Consumer<String, String> kafkaConsumer; 

    @Autowired // inject the bean from the application context that is wired with the mock bean 
    private MyService myService; 

    @Test 
    public void testClearSubscriptions() { 
     myService.clearSubscriptions(); 
     Mockito.verify(kafkaConsumer, Mockito.times(1)).unsubscribe(); 
    } 
} 
+0

Beachten Sie auch, ich habe gerade eine Dummy-Consumer-Klasse erstellt, weil ich nicht die tatsächliche Klasse in meiner Umgebung hatte –

+0

Gibt es eine Möglichkeit, dies mit SpringJUnit4ClassRunner.class auszuführen. Wenn ich es mit SpringJUnit4ClassRunner ausführe, erhalte ich einen Initialisierungsfehler der Anwendung, wenn ich von MockBean zu Mock für Consumer ändere, weil der Verbraucher AUTOWIRED in der Serviceklasse – StephCurry3093

+0

ist. Ich habe ein Beispiel mit SpringJUnit4ClassRunner in Kombination mit SpringBoots @MockBean Annotation hinzugefügt. Sie müssen sich an Ihre Umgebung/Konfiguration anpassen –