Kann Mockito eine Methode ohne Rücksicht auf das Argument beenden?

Lesezeit: 4 Minuten

Benutzer-Avatar
Erich Wilson

Ich versuche, einen Legacy-Code mit Mockito zu testen.

Ich möchte a stumpfen FooDao das in der Produktion wie folgt verwendet wird:

foo = fooDao.getBar(new Bazoo());

Ich kann schreiben:

when(fooDao.getBar(new Bazoo())).thenReturn(myFoo);

Aber das offensichtliche Problem ist das getBar() wird nie gleich mit genannt Bazoo Objekt, für das ich die Methode gestubpt habe. (Verflucht new Operator!)

Ich würde es lieben, wenn ich die Methode so abbrechen könnte, dass sie zurückkehrt myFoo unabhängig vom Argument. Andernfalls höre ich mir andere Problemumgehungsvorschläge an, aber ich möchte es wirklich vermeiden, den Produktionscode zu ändern, bis eine angemessene Testabdeckung vorhanden ist.

Benutzer-Avatar
Tomasz Nurkiewicz

when(
  fooDao.getBar(
    any(Bazoo.class)
  )
).thenReturn(myFoo);

oder (um zu vermeiden nulls):

when(
  fooDao.getBar(
    (Bazoo)notNull()
  )
).thenReturn(myFoo);

Vergessen Sie nicht, Matcher zu importieren (viele andere sind verfügbar):

Für Mockito 2.1.0 und neuer:

import static org.mockito.ArgumentMatchers.*;

Für ältere Versionen:

import static org.mockito.Matchers.*;

  • Ich liebe es, wenn die Antwort vor dem Ende des „Antwort-Einfrierens akzeptieren“ steht.

    – Eric Wilson

    11. Mai 2011 um 19:50 Uhr

  • Da ist ein notNull(Bazoo.class) genau wie die any(Bazoo.class) (Vielleicht existierte es zum Zeitpunkt dieser Antwort noch nicht)

    – Dandre Allison

    20. Februar 2013 um 22:07 Uhr

  • Ich hatte eine etwas besondere Situation, in der ich eines von zwei möglichen Argumenten haben konnte – Bazoo oder Cazoo das sind beide Unterklassen von, sagen wir, Azoo. zum Bazoo Ich musste zurück fooaber für Cazoo Ich musste zurück bar. in dieser Situation die vorgeschlagene Matchers.any() Lösung funktioniert aber nicht Matchers.isA() funktioniert perfekt.

    – Tanvir

    15. April 2014 um 14:57 Uhr


  • org.mockito.Matchers ist jetzt veraltet – verwenden org.mockito.ArgumentMatchers stattdessen, dh import static org.mockito.ArgumentMatchers.* (sehen Dokumente)

    – Nicht durch Null dividieren

    1. November 2017 um 13:38 Uhr

  • when(myFoo.knowsWhatsUp()).thenReturn(myMoney);

    – 6rchide

    29. Januar 2019 um 23:43 Uhr


Benutzer-Avatar
Buhb

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/Matchers.html

anyObject() sollte Ihren Bedürfnissen entsprechen.

Außerdem können Sie immer die Implementierung in Betracht ziehen hashCode() und equals() für die Bazoo Klasse. Dadurch würde Ihr Codebeispiel so funktionieren, wie Sie es möchten.

  • Stimmte mit dem zweiten Vorschlag überein, aber ich entscheide mich immer noch dafür, dies aus nicht-technischen Gründen nicht zu tun.

    – Eric Wilson

    11. Mai 2011 um 19:46 Uhr

  • Die Matchers-Klasse ist veraltet (siehe Dokumente“Diese Klasse wird wahrscheinlich in Version 3.0 entfernt”)

    – Johannes Rabauer

    10. Oktober 2019 um 6:52 Uhr

  • @JohannesRabauer Ich denke, es sollte geändert werden any() ?

    – golimar

    4. Mai 2021 um 9:19 Uhr

  • @golimar es sieht so aus, als würde dies genau dasselbe tun. any() und anyObject() sind laut den oben verlinkten Dokumenten gleich. Allerdings die komplette Matchers Klasse ist veraltet und die Klasse ArgumentMatchers sollte stattdessen verwendet werden.

    – Johannes Rabauer

    13. September 2021 um 13:42 Uhr

Verwenden Sie so:

when(
  fooDao.getBar(
    Matchers.<Bazoo>any()
  )
).thenReturn(myFoo);

Bevor Sie importieren müssen Mockito.Matchers

  • Das ist entwertet!

    – DrB

    5. Oktober 2018 um 15:36 Uhr

Benutzer-Avatar
José Martínez

Eine andere Möglichkeit ist, auf die gute alte Mode zu setzen equals Methode. Solange das Argument in der when spotten equals das Argument im getesteten Code, dann stimmt Mockito mit dem Mock überein.

Hier ist ein Beispiel.

public class MyPojo {

    public MyPojo( String someField ) {
        this.someField = someField;
    }

    private String someField;

    @Override
    public boolean equals( Object o ) {
        if ( this == o ) return true;
        if ( o == null || getClass() != o.getClass() ) return false;
        MyPojo myPojo = ( MyPojo ) o;
        return someField.equals( myPojo.someField );
    }

}

dann, vorausgesetzt, Sie wissen, wofür der Wert steht someField wird, können Sie es so verspotten.

when(fooDao.getBar(new MyPojo(expectedSomeField))).thenReturn(myFoo);

Vorteile: Das ist dann deutlicher any Matcher. Als Überprüfer von Code halte ich ein Auge offen für any in den Code schreiben Junior-Entwickler, da dieser einen Blick auf die Logik ihres Codes wirft, um das entsprechende übergebene Objekt zu generieren.

Nachteil: Manchmal ist das Feld, das an das Objekt übergeben wird, eine zufällige ID. Für diesen Fall können Sie das erwartete Argumentobjekt nicht einfach in Ihrem Scheincode konstruieren.

Ein weiterer möglicher Ansatz ist die Verwendung von Mockito Answer Objekt, das mit verwendet werden kann when Methode. Answer können Sie den eigentlichen Aufruf abfangen und das Eingabeargument untersuchen und ein Scheinobjekt zurückgeben. Im folgenden Beispiel verwende ich any um jede Anfrage an die Methode abzufangen, die verspottet wird. Aber dann im Answer Lambda, ich kann das Bazo-Argument weiter untersuchen … vielleicht um zu überprüfen, ob ihm eine richtige ID übergeben wurde. Das ist mir lieber any von selbst, so dass zumindest eine gewisse Überprüfung des Arguments durchgeführt wird.

    Bar mockBar = //generate mock Bar.

    when(fooDao.getBar(any(Bazo.class))
    .thenAnswer(  ( InvocationOnMock invocationOnMock) -> {
        Bazo actualBazo = invocationOnMock.getArgument( 0 );

        //inspect the actualBazo here and thrw exception if it does not meet your testing requirements.
        return mockBar;
    } );

Um es also zusammenzufassen: Ich verlasse mich gerne darauf equals (wobei das erwartete Argument und das tatsächliche Argument gleich sein sollten) und wenn gleich nicht möglich ist (da der Zustand des tatsächlichen Arguments nicht vorhergesagt werden kann), greife ich auf zurück Answer um das Argument zu überprüfen.

1359890cookie-checkKann Mockito eine Methode ohne Rücksicht auf das Argument beenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy