Mockito: InvalidUseOfMatchersException

140

Ich habe ein Befehlszeilentool, das eine DNS-Prüfung durchführt. Wenn die DNS-Prüfung erfolgreich ist, fährt der Befehl mit weiteren Aufgaben fort. Ich versuche, mit Mockito Unit-Tests dafür zu schreiben. Hier ist mein Code:

public class Command() {
    // ....
    void runCommand() {
        // ..
        dnsCheck(hostname, new InetAddressFactory());
        // ..
        // do other stuff after dnsCheck
    }

    void dnsCheck(String hostname, InetAddressFactory factory) {
        // calls to verify hostname
    }
}

Ich verwende InetAddressFactory, um eine statische Implementierung der InetAddressKlasse zu verspotten . Hier ist der Code für die Fabrik:

public class InetAddressFactory {
    public InetAddress getByName(String host) throws UnknownHostException {
        return InetAddress.getByName(host);
    }
}

Hier ist mein Unit-Testfall:

@RunWith(MockitoJUnitRunner.class)
public class CmdTest {

    // many functional tests for dnsCheck

    // here's the piece of code that is failing
    // in this test I want to test the rest of the code (i.e. after dnsCheck)
    @Test
    void testPostDnsCheck() {
        final Cmd cmd = spy(new Cmd());

        // this line does not work, and it throws the exception below:
        // tried using (InetAddressFactory) anyObject()
        doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class));
        cmd.runCommand();
    }
}

Ausnahme beim testPostDnsCheck()Testlauf:

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
2 matchers expected, 1 recorded.
This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));

Irgendwelche Eingaben, wie man das löst?

devang
quelle

Antworten:

283

Die Fehlermeldung beschreibt die Lösung. Die Linie

doNothing().when(cmd).dnsCheck(HOST, any(InetAddressFactory.class))

Verwendet einen Rohwert und einen Matcher, wenn entweder alle Rohwerte oder alle Matcher verwendet werden müssen. Eine korrekte Version könnte lauten

doNothing().when(cmd).dnsCheck(eq(HOST), any(InetAddressFactory.class))
Ryan Stewart
quelle
8
Wie dumm von mir. Ich analysierte weiter, warum der 2. Parameter mir immer wieder den Fehler gab. Danke fürs klarstellen. Ich bin sehr neu in Mockito, dies ist meine erste Begegnung.
Devang
32

Ich hatte schon lange das gleiche Problem, ich musste oft Matcher und Werte mischen und das habe ich mit Mockito nie geschafft ... bis vor kurzem! Ich habe die Lösung hier in der Hoffnung platziert, dass sie jemandem hilft, auch wenn dieser Beitrag ziemlich alt ist.

Es ist eindeutig nicht möglich, Matcher UND -Werte in Mockito zusammen zu verwenden, aber was ist, wenn ein Matcher akzeptiert, eine Variable zu vergleichen? Das würde das Problem lösen ... und tatsächlich gibt es: Gl

when(recommendedAccessor.searchRecommendedHolidaysProduct(eq(metas), any(List.class), any(HotelsBoardBasisType.class), any(Config.class)))
            .thenReturn(recommendedResults);

In diesem Beispiel ist 'metas' eine vorhandene Werteliste

Sam
quelle
5
Genial. org.mockito.Mockito.eq()
JavaPlease42
4
Der richtige Import ist jetzt org.mockito.ArgumentMatchers.eq ()
Sam
15

Es könnte jemandem in der Zukunft helfen: Mockito unterstützt (derzeit) nicht das Verspotten von "endgültigen" Methoden. Es gab mir das gleiche InvalidUseOfMatchersException.

Die Lösung für mich bestand darin, den Teil der Methode, der nicht "endgültig" sein musste, in eine separate, zugängliche und überschreibbare Methode zu integrieren.

Überprüfen Sie die Mockito-API für Ihren Anwendungsfall.

delucasvb
quelle
Dies half herauszufinden, warum mein Kotlin-Code mir Fehler geben würde, da alle Methoden in Kotlin endgültig sind!
sorry_I_wont
0

Trotz der Verwendung aller Matcher bekam ich das gleiche Problem:

"org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
Invalid use of argument matchers!
1 matchers expected, 3 recorded:"

Es dauerte eine Weile, bis ich herausfand, dass die Methode, die ich verspotten wollte, eine statische Methode einer Klasse (z. B. Xyz.class) war, die nur statische Methoden enthält, und ich vergaß, die folgende Zeile zu schreiben:

PowerMockito.mockStatic(Xyz.class);

Vielleicht hilft es anderen, da es auch die Ursache des Problems sein kann.

S Kumar
quelle
0

In meinem Fall wurde die Ausnahme ausgelöst, weil ich versucht habe, eine package-accessMethode zu verspotten . Als ich die Methodenzugriffsebene von packageauf protecteddie Ausnahme änderte, verschwand sie. ZB drinnen unterhalb der Java-Klasse,

public class Foo {
    String getName(String id) {
        return mMap.get(id);
    }
}

Die Methode String getName(String id)muss MINDESTENS sein protected , damit der Verspottungsmechanismus (Unterklassifizierung) funktionieren kann.

shizhen
quelle