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?

Elad Benda2
quelle
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 .

Roland Weisleder
quelle
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 {
    // ...
  }
}
Stefan Birkner
quelle
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>
Gjera
quelle
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;

Rammgarot
quelle
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.

Z3d4s
quelle
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!

Ganesh Satpute
quelle
2
  1. Sie sollten @RunWith(SpringJUnit4ClassRunner.class)in Ihrer Klasse verwenden
  2. Sie müssen die MockitoAnnotations.initMocks(this);@ Before-Methode aufrufen
Enoder
quelle
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

Versuchen Sie zu überprüfen, ob die von Ihnen aufgerufene Methode endgültig ist Methode Methode ist oder nicht.

Mockito kann die endgültige Methode nicht verspotten. https://github.com/mockito/mockito/wiki/FAQ

UmAnusorn
quelle
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.

Amanatee
quelle
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>
Suhas Karanth
quelle
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?
Dan Gravell
quelle
-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 .

Sam
quelle