web-dev-qa-db-fra.com

Mockito ArgumentMatcher disant que les arguments sont différents

J'utilise Mockito pour les tests unitaires et ArgumentMatcher pour vérifier si un champ particulier d'un argument a une valeur particulière.

J'ai une classe StatusMatcher qui étend ArgumentMatcher et vérifie si un objet de la classe MyClass a une valeur particulière dans le champ status. La façon dont j'invoque cela dans les tests est la suivante:

verify(myDAO, times(1)).update(argThat(new StatusMatcher("SomeStatus")));

Ici, update est la méthode du DAO appelé avec un objet MyClass. Je veux voir s'il a le bon statut ou pas. Voici ce que je reçois:

Argument(s) are different! Wanted:
myDAO.update(
    <Status matcher>
);
-> at com.foo.bar.MyTest.test1 
Actual invocation has different arguments:
myDAO.update(
    com.foo.bar.MyClass
);

Notez que cela fonctionne parfaitement pour tous les cas de test, sauf un cas de test. Je sais donc que les StatusMatcher, etc. ont été codés correctement. Je ne suis pas sûr de ce qui est différent de la méthode qui obtient cette exception.

Ce que je veux savoir, c’est: dans quelles conditions l’argumentMatcher lève une telle exception afin que je puisse découvrir ce qui m’a manqué (il ne m’appartient pas de coller les codes de méthode actuels) Veuillez me dire si l’explication n’est pas assez claire et Je vais essayer de l'améliorer. Merci d'avoir lu jusqu'ici :)

EDIT: Voici le code de ma classe StatusMatcher

    private class StatusMatcher extends ArgumentMatcher<MyClass> {

    private String status;
    public StatusMatcher(String hs) { 
        status = hs;
    }

    @Override
    public boolean matches(Object argument) {

        return status.equals(((MyClass)argument).getStatus());
    } 
}
11
Mustafa Hussain

Comme vous l'avez dit, cela échoue car les arguments sont différents. Jetez un coup d'œil au test ci-dessous et vous verrez que la deuxième méthode de test échouera car le statut de votre instance MyClass est différent de SomeStatus que vous avez transmis dans le matcher.

public class MatcherTest {

    class MyClass{
        private String status;

        MyClass(String status) {
            this.status = status;
        }

        public String getStatus(){
            return status;
        }
    }

    class MyDao {
        public void update(MyClass myClass){}
    }

    class StatusMatcher extends ArgumentMatcher<MyClass> {
        private String status;
        public StatusMatcher(String hs) {
            status = hs;
        }

        @Override
        public boolean matches(Object argument) {
            return status.equals(((MyClass)argument).getStatus());
        }
    }

    @Test
    public void shouldMatchStatus(){
        MyDao mock = mock(MyDao.class);
        mock.update(new MyClass("expectedStatus"));
        verify(mock, times(1)).update(argThat(new StatusMatcher("expectedStatus")));
    }

    @Test
    public void shouldNotMatchStatus(){
        MyDao mock = mock(MyDao.class);
        mock.update(new MyClass("unexpectedStatus"));
        /* THE BELLOW WILL FAIL BECAUSE ARGUMENTS ARE DIFFERENT */
        verify(mock, times(1)).update(argThat(new StatusMatcher("expectedStatus")));
    }
}

Je pourrais très bien présumer que vous pourriez réutiliser des variables ou avoir un champ statique, etc., mais si vous ne voyez pas votre code de test, personne ne peut le savoir.

9
Morfic

J'ai aussi fait face à ce problème. Ci-dessous l'erreur et sa solution:

error: Argument(s) are different! Wanted:

    tradeMaintenanceDao.updateTradesMaintData(.....

J'ai utilisé la déclaration suivante pour le résoudre:

verify(tradeMaintenanceDao, times(1))
    .updateTradesMaintData(anyString(), anyList(), anyList(), anyString(), anyString());

La cause initiale était:

verify(tradeMaintenanceDao, times(1)).updateTradesMaintData(userName, tradeStatusList, tradeReasonList, notes, pendStatus);
1
Rajkumar Pallerla