Die Scheininstanz ist nach der @ Mock-Annotation null


74

Ich versuche diesen Test auszuführen:

    @Mock IRoutingObjHttpClient routingClientMock;
    @Mock IRoutingResponseRepository routingResponseRepositoryMock;


    @Test
    public void testSendRoutingRequest() throws Exception {
        CompleteRoutingResponse completeRoutingResponse = new CompleteRoutingResponse();
        completeRoutingResponse.regression_latencyMillis = 500L;

        Mockito.when(routingClientMock.sendRoutingRequest(any(RoutingRequest.class))).thenReturn(completeRoutingResponse);

        RoutingObjHttpClientWithReRun routingObjHttpClientWithReRun = new RoutingObjHttpClientWithReRun
                (routingClientMock, routingResponseRepositoryMock);

...
    }

aber ich bekomme NullPointerException für:

Mockito.when(routingClientMock.

Was vermisse ich?


8
Haben Sie anrufen MockitoAnnotations.initMocks(this)? (Sollte sich wahrscheinlich in der @ Vor-Methode befinden.) Oder haben Sie eine andere @ Regel, mit der Sie Ihre Mocks initialisieren möchten? (Es ist nicht automagisch)
Andy Turner

Sie müssen die routingClientMockzBroutingClientMock = Mockito.mock(RoutingObjHtttpClient.class);
Tim Biegeleisen

Sie können auch @RunWith(MockitoJUnitRunner.class)in Ihrer Klasse verwenden
Roland Weisleder

Bitte schreiben Sie als Antwort und ich werde es markieren
Elad Benda2

Antworten:


97

Wenn Sie die @MockAnmerkung verwenden möchten, sollten Sie die verwendenMockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @Mock
    private IRoutingObjHttpClient routingClientMock;

    @Test
    public void testSendRoutingRequest() throws Exception {
        // ...
    }

}

Siehe auch dieses Tutorial .


1
Es funktioniert nicht für mich gibt immer den Fehler "dexcache == null (und es konnte kein Standard gefunden werden; erwägen, die Systemeigenschaft 'dexmaker.dexcache' festzulegen)"
pyus13

@ pyus13 Dies sollte eine neue Frage mit mehr Code sein.
Roland Weisleder

Schätzen Sie die Antwort, ich glaube, das Problem war, dass ich sie in JUnit Test verwendet habe, und während ein Teil des Codes jemanden aus dem Team zusammenführt, hat er fälschlicherweise Abhängigkeiten von Dex Maker TestImplementation hinzugefügt. Nachdem diese Zeile aus build.gradle entfernt wurde, begannen die Dinge zu funktionieren. Vielen Dank, ich hoffe, dies spart jemandem Zeit.
Pyus13

Durch die Verwendung der @ Mock-Annotation ist das Erstellen eines Builds fehlgeschlagen.
David

@ David Ich denke, Ihr Problem sollte eine neue Frage mit einem vollständigen Beispiel sein.
Roland Weisleder

57

Sie haben drei Möglichkeiten, um die @MockAnnotation zu aktivieren : MockitoRule, MockitoJUnitRunner, MockitoAnnotations.initMocks (this). IMHO mit der MockitoRuleist die beste, weil Sie damit immer noch einen anderen Läufer wie z Parameterized.

Verwenden Sie die MockitoRule

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Rule
  public MockitoRule rule = MockitoJUnit.rule();

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

Verwenden Sie den MockitoJUnitRunner

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

Rufen Sie MockitoAnnotations.initMocks (this) explizit auf.

Dies kann in der qn- @BeforeMethode, in Ihrem eigenen Läufer oder in einer eigenen Regel erfolgen.

public class MockitoTest {

  @Mock
  private IRoutingObjHttpClient routingClientMock;

  @Before
  public void createMocks() {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testSendRoutingRequest() throws Exception {
    // ...
  }
}

In den meisten Testklassen funktioniert @RunWith (MockitoJUnitRunner.class) gut beim Injizieren von Mocks. In einigen Testklassen arbeiteten jedoch sowohl @RunWith (MockitoJUnitRunner.class) als auch MockitoAnnotations.initMocks (this) nur zusammen. Gibt es eine Erklärung für dieses Problem?
Nakul Goyal

Können Sie bitte eine weitere Frage zu StackOverflow mit einem vollständigen Beispiel erstellen?
Stefan Birkner

17

Das gleiche Problem kann auftreten, wenn Sie Junit5 verwenden, da keine Annotation '@RunWith' mehr vorhanden ist.

In diesem Fall sollten Sie Ihre Klasse mit folgenden Anmerkungen versehen:

@ExtendWith(MockitoExtension.class)
public class MyTestClass {
...

Sie sollten auch in Ihre Abhängigkeit importieren (Maven - pom.xml):

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>${mockito.version}</version>
    <scope>test</scope>
</dependency>

Dies ist sehr wahrscheinlich die richtige Lösung für die meisten Leute, die diesen Thread heutzutage lesen.
Rouven H.

Diese Antwort hat mir buchstäblich das Leben gerettet und sollte wahrscheinlich ganz oben in allen Antworten +1 aufgeführt werden.
Tim Biegeleisen

14

Wenn Sie junit.jupitermit @ExtendWith(MockitoExtension.class)für Testklasse aber Mocks sind null , stellen Sie sicher , dass @TestAnnotation von importiert

import org.junit.jupiter.api.Test;

Anstatt von org.junit.Test;


4

Dies kann auch ein Importproblem sein. Stellen Sie daher sicher, dass Sie über das entsprechende importierte Paket verfügen.

Zum Beispiel hat das "org.easymock" -Paket auch eine Anmerkung namens @Mock, die natürlich nicht mit Mockito-spezifischen Setups funktioniert.


4

Für mich hat es auch nach dem Hinzufügen @RunWith(MockitoJUnitRunner.class)nicht funktioniert.
Es stellte sich heraus, hatte ich den dummen Fehler des Imports aus @Testaus

import org.junit.jupiter.api.Test;

Anstatt von

import org.junit.Test;

Nach der Korrektur hat es funktioniert!


2
  1. Sie sollten @RunWith(SpringJUnit4ClassRunner.class)in Ihrer Klasse verwenden
  2. Sie müssen die MockitoAnnotations.initMocks(this);@ Before-Methode aufrufen

2
warum @RunWith(SpringJUnit4ClassRunner.class)nicht MockitoJUnitRunner.class?
Elad Benda2

Sie benötigen SpringJUnit4ClassRunner nur, wenn Sie einen Spring-Kontext in Ihren Test einbinden möchten - was für sich genommen eine sehr kurvenreiche Passage ist.
David Victor


1

Was hat dieses Problem für mich gelöst (Kombination der obigen Antworten und meiner eigenen Ergänzungen):

  • MockitoAnnotations.initMocks(this); in dem @Before Methode
  • Die Testklasse muss öffentlich sein
  • Testmethoden müssen öffentlich sein
  • import org.junit.Test; Anstatt von import org.junit.jupiter.api.Test;

Wenn Sie Befehl + N -> Test...in Intellij ausführen, wird (zumindest standardmäßig) ein Boilerplate generiert, das in meinem Fall nicht funktioniert hat.


Vielen Dank, dass du mich gerettet hast. Mein Problem war das letzte, das Sie kommentiert haben. Viel Liebe!
CodeMonkey

0

Für mich Hinzufügen der Anmerkung zur Klasse:

@RunWith(MockitoJUnitRunner.class)

Durch Ändern der Version von Mockito wurde dieses Problem behoben.

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.23.4</version>
        <scope>test</scope>
</dependency>

0

Ich hatte das gleiche Problem, fand jedoch eine Aktualisierung meiner Tests (die ursprünglich für JUnit 3 geschrieben wurden und das Legacy setUp()und verwendetentearDown() Methoden verwendeten) auf JUnit 4 funktionierte und moderne kommentierte Fixture-Methoden funktionierten.

Wenn Sie außerdem die Regel verwenden:

@Rule public MockitoRule rule = MockitoJUnit.rule();

Stellen Sie sicher, dass sich die Regel auch in einer öffentlichen Klasse befindet. Andernfalls erhalten Sie die folgende Nachricht:

How did getFields return a field we couldn't access?

-4

Wenn Sie dann auch PowerMock verwenden

@RunWith(MockitoJUnitRunner.class)

kann durch ersetzt werden

@RunWith(PowerMockRunner.class)

Dadurch wird Ihre aktiviert @Mocksund die PowerMock-Funktionalität aktiviert .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.