web-dev-qa-db-fra.com

Mockito: InvalidUseOfMatchersException

J'ai un outil de ligne de commande qui effectue une vérification DNS. Si la vérification DNS réussit, la commande exécute d'autres tâches. J'essaie d'écrire des tests unitaires à l'aide de Mockito. Voici mon 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
    }
}

J'utilise InetAddressFactory pour simuler une implémentation statique de la classe InetAddress. Voici le code pour l'usine:

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

Voici mon cas de test unitaire:

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

Exception sur l'exécution du test testPostDnsCheck():

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

Des commentaires sur la façon de résoudre ce problème? 

97
devang

Le message d'erreur décrit assez clairement la solution. La ligne

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

utilise une valeur brute et un adaptateur, lorsqu'il est nécessaire d'utiliser toutes les valeurs brutes ou tous les agents de correspondance. Une version correcte peut lire

doNothing().when(cmd).dnsCheck(eq(Host), any(InetAddressFactory.class))
206
Ryan Stewart

J'avais le même problème depuis longtemps maintenant, j'avais souvent besoin de mélanger des Matchers et des valeurs et je n'ai jamais réussi à le faire avec Mockito .... jusqu'à récemment! ce post est assez vieux.

Il n’est clairement pas possible d’utiliser les Matchers ET les valeurs ensemble dans Mockito, mais que se passerait-il si un Matcher acceptait de comparer une variable? Cela résoudrait le problème ... et en fait il y a: eq

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

Dans cet exemple, "metas" est une liste de valeurs existante.

24
sam

Cela pourrait aider quelqu'un dans le futur: Mockito ne supporte pas les moqueries des méthodes "finales" (pour le moment). Cela m'a donné la même InvalidUseOfMatchersException.

La solution pour moi était de mettre la partie de la méthode qui n'avait pas besoin d'être "finale" dans une méthode séparée, accessible et pouvant être remplacée.

Consultez l’API Mockito pour votre cas d’utilisation.

9
delucasvb

Malgré l'utilisation de tous les matchers, le même problème se posait:

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

Il m'a fallu peu de temps pour comprendre que la méthode que je tentais de simuler était une méthode statique d'une classe (disons Xyz.class) qui ne contenait qu'une méthode statique et j'ai oublié d'écrire la ligne suivante:

PowerMockito.mockStatic(Xyz.class);

Peut-être que cela aidera les autres, car cela pourrait également être la cause du problème.

0
S Kumar

Dans mon cas, l'exception a été déclenchée car j'ai tenté de me moquer d'une méthode package-access. Lorsque j'ai changé le niveau d'accès à la méthode de package à protected l'exception a disparu. Par exemple. à l'intérieur de la classe Java,

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

la méthode String getName(String id) doit être AU MOINSprotected niveau pour que le mécanisme de mocking (sous-classement) puisse fonctionner.

0
shizhen