Работает ли сопоставление с argThat только для методов с одним аргументом?
У меня есть следующий вызов метода в моем тестируемом классе:
class ClassUnderTest {
[...]
restTemplate.getForEntity(url, MyResponseEntity.class, parameterMap);
[...]
}
В модульном тесте класса, содержащего эту строку, я хочу заглушить метод getForEntity
таким образом, чтобы он возвращал разные ответы для разных записей в parameterMap
.
Используя BDDMockito, я пытаюсь сопоставить, что нужный параметр является частью parameterMap, используя argThat
:
@InjectMocks
private ClassUnderTest classUnderTest;
@Mock
private RestTemplate restTemplate;
[...]
given(restTemplate.getForEntity(anyString(), any(Class.class), argThat(hasEntry("myKey", "myValue"))
.willReturn(responseEntityA);
Однако, если я выполняю тест таким образом, что parameterMap
содержит (Я проверил это в отладчике) ключ " myKey" и значение "myValue", я получаю NullPointerException
, потому что mockito, кажется, не может сопоставить вызов метода с заглушкой, которую я создал.
С другой стороны, использование следующего очень общего сопоставления позволяет мне выполнять мои тесты без NPE, предоставляя ответ по умолчанию для всех вызовов, однако это не позволяет мне определить пользовательский ответ для данного параметра.
given(restTemplate.getForEntity(anyString(), any(Class.class), anyMap())
.willReturn(defaultResponseEntity);
В чем причина этого? Работает ли argThat
только для методов с одним параметром?
Есть другой способ сопоставить вызовы getEntity
с картой, содержащей определенную пару (ключ, значение)?
2 ответа:
argThat
безусловно, работает для более чем одного параметра, и нет ничего явно неправильного в том, что вы пытаетесь сделать. У меня есть ноющее предчувствие, что он выбирает неправильную перегрузку :getForEntity(String url, Class<T> responseType, Map<String,?> urlVariables) getForEntity(String url, Class<T> responseType, Object... urlVariables)
Если генераторы не совсем совпадают, Java может предположить, что ваш
hasEntry
лучше всего соответствует методуObject...
, где вашanyMap
соответствует методуMap<String, ?>
. В этом случае вы бы заглушили перегрузку, которую вы не вызываете (Object...
), и Mockito вернулся бы к значениям по умолчанию для того, который вы вызываете. фактически вызывая тестируемую систему (Map<String, ?>
). Наведение указателя мыши на вызов метода в IDE может пролить свет на то, какая перегрузка соответствует компилятору.Чтобы дать Java лучшую подсказку, попробуйте приведение, которое будет выглядеть так (предупреждение, не проверено или проверено):
given(restTemplate.getForEntity( anyString(), any(Class.class), (Map<String, ?>) argThat(hasEntry("myKey", "myValue")))) .willReturn(responseEntityA);