Mockito: InvalidUseOfMatchersException


141

Ho uno strumento da riga di comando che esegue un controllo DNS. Se il controllo DNS ha esito positivo, il comando procede con ulteriori attività. Sto provando a scrivere test unitari per questo usando Mockito. Ecco il mio codice:

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

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

Sto usando InetAddressFactory per deridere un'implementazione statica della InetAddressclasse. Ecco il codice per la fabbrica:

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

Ecco il mio caso di test unitario:

@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();
    }
}

Eccezione durante l'esecuzione del testPostDnsCheck()test:

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"));

Qualche input su come risolverlo?

Risposte:


283

Il messaggio di errore delinea la soluzione. La linea

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

utilizza un valore non elaborato e un corrispondente, quando è necessario utilizzare tutti i valori non elaborati o tutti i corrispondenti. Potrebbe leggere una versione corretta

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

8
Che sciocco sono. Ho continuato ad analizzare perché il secondo parametro ha continuato a darmi l'errore. Grazie per il chiarimento. Sono molto nuovo con Mockito, questo è il mio primo incontro.
Devoto il

32

Ho avuto lo stesso problema da molto tempo ormai, spesso dovevo mescolare Matcher e valori e non sono mai riuscito a farlo con Mockito .... fino a poco tempo fa! Ho messo la soluzione qui sperando che possa aiutare qualcuno anche se questo post è piuttosto vecchio.

Chiaramente non è possibile usare Matchers AND valori insieme in Mockito, ma cosa accadrebbe se un Matcher accettasse di confrontare una variabile? Ciò risolverebbe il problema ... e infatti c'è: eq

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

In questo esempio "metas" è un elenco esistente di valori


5
Eccezionale. org.mockito.Mockito.eq()
javaPlease42

4
l'importazione corretta è ora org.mockito.ArgumentMatchers.eq ()
sam

15

Potrebbe aiutare qualcuno in futuro: Mockito non supporta la derisione dei metodi "finali" (in questo momento). Mi ha dato lo stesso InvalidUseOfMatchersException.

La soluzione per me era quella di mettere la parte del metodo che non doveva essere "finale" in un metodo separato, accessibile e scavalcabile.

Esamina l' API Mockito per il tuo caso d'uso.


Questo mi ha aiutato a capire perché il mio codice kotlin mi avrebbe dato un errore, perché tutti i metodi in kotlin sono definitivi!
sorry_I_wont

0

Nonostante l'utilizzo di tutti i matcher, stavo riscontrando lo stesso problema:

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

Mi ci è voluto poco per capire che il metodo che stavo cercando di deridere era un metodo statico di una classe (diciamo Xyz.class) che contiene solo un metodo statico e ho dimenticato di scrivere la seguente riga:

PowerMockito.mockStatic(Xyz.class);

Può essere che aiuterà gli altri in quanto potrebbe anche essere la causa del problema.


0

Nel mio caso, l'eccezione è stata sollevata perché ho cercato di deridere un package-accessmetodo. Quando ho cambiato il livello di accesso metodo dal packageal protectedl'eccezione è andato via. Ad esempio all'interno della classe Java,

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

il metodo String getName(String id)deve essere almeno AL protected livello in modo che il meccanismo di derisione (sottoclasse) possa funzionare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.