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"));
Любые данные о том, как это решить?
Ответы
Ответ 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 для вашего использования.