169 votes

Mockito : InvalidUseOfMatchersException

J'ai un outil en ligne de commande qui effectue une vérification du DNS. Si la vérification DNS réussit, la commande passe à d'autres tâches. J'essaie d'écrire des tests unitaires pour cet outil en utilisant 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 l'algorithme de l'adresse IP. InetAddress classe. Voici le code de la fabrique :

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 lors de l'exécution 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"));

Avez-vous une idée de la façon de résoudre ce problème ?

342voto

Ryan Stewart Points 46960

Le message d'erreur présente la solution. La ligne

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

utilise une valeur brute et une correspondance, alors qu'il est nécessaire d'utiliser soit toutes les valeurs brutes, soit toutes les correspondances. Une version correcte pourrait être la suivante

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

40voto

sam Points 240

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 ! Je mets la solution ici en espérant que cela aidera quelqu'un même si ce post est assez ancien.

Il est clairement impossible d'utiliser les Matchers ET les valeurs ensemble dans Mockito, mais que se passerait-il s'il y avait un Matcher acceptant de comparer une variable ? Cela résoudrait le problème... et en fait il y en a un : 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.

20voto

delucasvb Points 901

Cela pourrait aider quelqu'un à l'avenir : Mockito ne supporte pas le mocking des méthodes 'final' (pour le moment). Il m'a donné le même InvalidUseOfMatchersException .

Pour moi, la solution consistait à placer la partie de la méthode qui ne devait pas être "finale" dans une méthode distincte, accessible et surchargeable.

Passez en revue le API de Mockito pour votre cas d'utilisation.

1voto

shizhen Points 2702

Dans mon cas, l'exception a été levée parce que j'ai essayé de simuler un package-access méthode. Lorsque j'ai changé le niveau d'accès à la méthode de package a protected l'exception a disparu. Par exemple, dans la classe Java ci-dessous,

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

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

0voto

S Kumar Points 192

Malgré l'utilisation de tous les matchers, j'ai eu le même problème :

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

Cela m'a pris un peu de temps pour comprendre que la méthode que j'essayais de simuler était une méthode statique d'une classe (disons Xyz.class) qui ne contient que des méthodes statiques et j'ai oublié d'écrire la ligne suivante :

PowerMockito.mockStatic(Xyz.class);

Peut-être que cela aidera d'autres personnes car cela peut aussi être la cause du problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X