Подтвердить что ты не робот

Mockito: InvalidUseOfMatchersException

У меня есть инструмент командной строки, который выполняет проверку DNS. Если проверка DNS завершается успешно, команда выполняет дополнительные задачи. Я пытаюсь написать модульные тесты для этого, используя Mockito. Здесь мой код:

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

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

Я использую InetAddressFactory для моделирования статической реализации класса InetAddress. Здесь код для factory:

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

Здесь мой unit test случай:

@RunWith(MockitoJUnitRunner.class)
public class CmdTest {

    // many functional tests for dnsCheck

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

Исключение при запуске теста 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"));

Любые данные о том, как это решить?

4b9b3361

Ответ 1

Сообщение об ошибке четко отображает решение. Строка

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

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

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

Ответ 2

У меня была такая же проблема в течение длительного времени, мне часто приходилось смешивать Matchers и ценности, и я никогда не делал этого с Mockito... до недавнего времени! Я поставил решение здесь, надеясь, что это поможет кому-то, даже если этот пост довольно старый.

В Mockito явно не возможно использовать ИМЯ и ИМЯ, но что, если бы был Matcher, принимающий сравнение переменной? Это решило бы проблему... и на самом деле есть: eq

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

В этом примере "metas" - это существующий список значений

Ответ 3

Это может помочь кому-то в будущем: Mockito не поддерживает насмешку "окончательных" методов (прямо сейчас). Это дало мне то же самое InvalidUseOfMatchersException.

Решение для меня состояло в том, чтобы поместить часть метода, которая не должна быть "окончательной" в отдельном, доступном и переопределяемом методе.

Просмотрите Mockito API для вашего использования.