Mockito ArgumentMatchers

1. Общ преглед

Този урок показва как да използвате ArgumentMatcher и как той се различава от ArgumentCaptor .

За въведение в рамката на Mockito, моля, вижте тази статия.

2. Зависимости на Maven

Трябва да добавим един артефакт:

 org.mockito mockito-core 2.21.0 test 

Най-новата версия на Mockito може да бъде намерена в Maven Central .

3. ArgumentMatchers

Възможно е конфигуриране на подиграван метод по различни начини. Едно от тях е да върне фиксирани стойности:

doReturn("Flower").when(flowerService).analyze("poppy");

В горния пример String “Flower” се връща само когато услугата за анализ получи String “мак”.

Но може би трябва да отговорим на по-широк диапазон от стойности или предварително неизвестни стойности .

Във всички тези сценарии, можем да конфигурираме нашите подиграваха методи с аргумент кибрит :

when(flowerService.analyze(anyString())).thenReturn("Flower");

Сега, поради съвпадението на аргументи anyString , резултатът ще бъде същият, без значение каква стойност предаваме за анализ. ArgumentMatchers ни позволява гъвкава проверка или забиване.

В случай, че методът има повече от един аргумент, не е възможно да се използват ArgumentMatchers само за някои от аргументите . Mockito изисква да предоставите всички аргументи или чрез съвпадения, или чрез точни стойности.

Следващ пример е неправилен подход към това:

abstract class FlowerService { public abstract boolean isABigFlower(String name, int petals); } FlowerService mock = mock(FlowerService.class); when(mock.isABigFlower("poppy", anyInt())).thenReturn(true);

За да го поправим и да запазим името на String „мак“, както е желано, ще използваме eq matcher :

when(mock.isABigFlower(eq("poppy"), anyInt())).thenReturn(true);

Има още две точки, за които да се погрижите, когато се използват мачове :

  • Не можем да ги използваме като стойност за връщане , точна стойност се изисква при забиване на обаждания
  • И накрая, не можем да използваме съвпадения на аргументи извън проверка или забиване

В последния случай Mockito ще открие изгубения аргумент и ще хвърли InvalidUseOfMatchersException .

Лош пример може да бъде:

String orMatcher = or(eq("poppy"), endsWith("y")); verify(mock).analyze(orMatcher);

Начинът за изпълнение на горния код е:

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

Mockito също така предоставя AdditionalMatchers за изпълнение на общи логически операции ('not', 'и', 'или') на ArgumentMatchers, които съответстват както на примитивни, така и на непримитивни типове:

verify(mock).analyze(or(eq("poppy"), endsWith("y")));

4. Съвпадение на потребителски аргументи

Създаването на нашето съвпадение може да бъде добре, за да изберете най-добрия възможен подход за даден сценарий и да направите тест с най-високо качество , който е чист и поддържаем.

Например, може да имаме MessageController, който доставя съобщения. Той ще получи MessageDTO и оттам ще създаде съобщение, което да бъде доставено от MessageService .

Нашата проверка ще бъде проста, проверете дали сме извикали MessageService точно 1 път с всяко съобщение:

verify(messageService, times(1)).deliverMessage(any(Message.class));

Тъй като Съобщението е изградено вътре в тествания метод , ние сме принудени да използваме всяко като съвпадение .

Този подход не ни позволява да проверяваме данните в съобщението , които могат да бъдат различни в сравнение с данните в MessageDTO .

Поради тази причина ще приложим съвпадение на потребителски аргументи:

public class MessageMatcher implements ArgumentMatcher { private Message left; // constructors @Override public boolean matches(Message right) { return left.getFrom().equals(right.getFrom()) && left.getTo().equals(right.getTo()) && left.getText().equals(right.getText()) && right.getDate() != null && right.getId() != null; } }

За да използваме нашето съвпадение, трябва да модифицираме нашия тест и да заменим всеки от argThat :

verify(messageService, times(1)).deliverMessage(argThat(new MessageMatcher(message)));

Сега знаем, че нашият екземпляр на Message ще има същите данни като нашия MessageDTO .

5. Съвпадение на потребителски аргументи срещу ArgumentCaptor

И двете техники за съвпадение на аргументи и ArgumentCaptor могат да се използват, за да се уверят, че определени аргументи са били предадени на макети.

Въпреки това, ArgumentCaptor може да бъде по-добър баланс, ако имаме нужда от него, за да отстояват по аргумент стойности за пълна проверка или нашия обичай аргумент за съотнасяне не може да се използва повторно .

Персонализираните аргументи за съвпадение чрез ArgumentMatcher обикновено са по-добри за потискане.

6. Заключение

В тази статия разгледахме характеристика на Mockito , ArgumentMatcher и разликата с ArgumentCaptor .

Както винаги, пълният изходен код на примерите е достъпен в GitHub.