Mockito ArgumentMatcher говорит, что аргументы разные

Я использую Mockito для модульного тестирования, и я использую ArgumentMatcher, чтобы проверить, имеет ли конкретное поле аргумента определенное значение.

у меня есть класс StatusMatcher, который расширяет ArgumentMatcher и проверяет, имеет ли объект класса MyClass определенное значение в поле состояния. Способ, которым я вызываю это в тестах:

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

здесь update - Это метод DAO, который вызывается с некоторым объектом MyClass. Я хочу посмотреть, есть ли у него правильный статус или нет. Вот что я получаю:

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

обратите внимание, что это отлично работает для всех тестовых случаев, кроме одного тестового случая. Поэтому я знаю StatusMatcher и т. д. были закодированы правильно. Я не уверен, что отличается от метода, где он получает это исключение.

что я хочу знать: при каких условиях ArgumentMatcher выбросит такое исключение, чтобы я мог узнать, что мне не хватает (мне не нужно вставлять фактические коды методов) Пожалуйста скажите мне, если объяснение недостаточно ясно, и я постараюсь его улучшить. Спасибо, что прочитали это далеко:)

EDIT: вот код для моего класса 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());
    } 
}

2 ответов


как вы сказали, это не потому, что аргументы разные. Взгляните на тест ниже, и вы увидите, что второй метод теста потерпит неудачу, потому что статус в вашем MyClass экземпляр отличается от SomeStatus что вы прошли в матче.

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

я мог бы предположить, что вы можете повторно использовать переменные или иметь статическое поле и т. д., Но, не видя вашего тестового кода, никто не может сказать.


Я также столкнулся с этой проблемой. Ниже приведена ошибка и ее решение:

error: Argument(s) are different! Wanted:

    tradeMaintenanceDao.updateTradesMaintData(.....

я использовал следующий оператор для его решения:

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

первоначальная причина была:

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