different types matchers provided mockito
нови функции в java 8 с примери
Въведение в различните видове мачове в Mockito.
Подигравки и шпиони в Mockito бяха обяснени подробно в нашия предишен урок на подробно Mockito тренировъчна поредица .
Какво са Matchers?
Съвпаденията са като регулярни изрази или заместващи символи, където вместо конкретен вход (и / или изход), вие посочвате диапазон / тип вход / изход, въз основа на който мъничетата / шпионите могат да бъдат почиващи и повикванията към мъничките могат да бъдат проверени.
Всички мачове на Mockito са част от „ Mockito ’ статичен клас.
Съвпаденията са мощен инструмент, който позволява стенографски начин за настройване на заглушки, както и проверка на извикванията на заглушителите, като се споменават аргументите като общи типове до конкретни стойности в зависимост от случая на употреба или сценария.
Какво ще научите:
Видове мачове в Mockito
В Mockito има общо 2 вида мачове или по отношение на използването, съвпадения могат да се използват за следните 2 категории:
- Съвпадения на аргументи по време на настройка на Stub
- Проверка на съвпаденията за проверка на действителните повиквания към заглушители
И за двата вида Съвпадения, т.е. Аргумент и Проверка, Mockito предлага огромен набор от съвпадения (Щракнете тук за да получите пълен списък на състезателите).
Съвпадения на аргументи
По-долу са изброени най-широко използваните:
За всичко по-долу, нека помислим за тестване на IntegerList:
final List mockedIntList = mock(ArrayList.class);
# 1) any () - Приема всеки обект (включително null).
when (mockedIntList.get( any ())).thenReturn(3);
# две) всеки (клас на езика на Java) -
Пример : any (ClassUnderTest.class) - Това е по-специфичен вариант на any () и ще приема само обекти от типа клас, който е споменат като параметър на шаблона.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
# 3) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () и много други - Всички те приемат всеки обект от съответния тип данни, както и нулеви стойности.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) Конкретни аргументи - В случаите, когато действителните аргументи са известни предварително, винаги се препоръчва да се използват, тъй като те осигуряват по-голяма увереност спрямо родовите типове аргументи.
Пример:
when(mockedIntList.get(1)).thenReturn(3);
Проверка на съвпаденията
Има някои специализирани мачове, които могат да се очакват / отстояват неща като не. на призовавания по подигравка.
За всички съвпадения по-долу, нека разгледаме същия списък с примери, който сме използвали преди.
final List mockedIntList = mock(ArrayList.class);
# 1) Присмехулни призиви
(i) Простото извикване на Mock проверява дали измисленият метод е бил извикан / взаимодействал или не, като настроите размера на подигравания списък на 5.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList).size();
(ii) Конкретен брой взаимодействия с подиграван метод потвърждава броя на не. от моментите се очакваше да бъде извикан.
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(1)).size();
За да проверите за 0 взаимодействия, просто променете стойността от 1 на 0 като аргумент за съвпадение на times ().
//arrange when(mockedList.size()).thenReturn(5); // act int size = mockedList.size(); // assert verify(mockedList, times(0)).size();
В случай на откази, той връща следните изключения:
да се) Когато очакваните извиквания са по-малко от действителните извиквания:
Пример: Търси се 2 пъти, но се извиква 3 пъти, след което Mockito се връща - “ проверка.TooManyActualInvocations '
Примерен код:
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(2)).get(anyInt());
б) Когато очакваните извиквания са повече от действителните извиквания:
Пример: Търси се 2 пъти, но се извиква 1 път, след което Mockito се връща - “ проверка.TooLittleActualInvocations '
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(3); response = mockedIntList.get(100); // Assert verify(mockedIntList, times(4)).get(anyInt());
(iii) Няма взаимодействия със специфичния метод на подигравания обект.
final List mockedIntList = mock(ArrayList.class); // Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); // Assert verify(mockedIntList, never()).size();
(iv) Проверка на реда на подигравани взаимодействия - Това е особено полезно, когато искате да осигурите реда, в който са извикани методите на подиграваните обекти.
Пример: База данни като операции, при които тестът трябва да провери реда, в който са се случили актуализациите на базата данни.
За да илюстрираме това чрез пример - Нека продължим със същия списък с примери.
Сега нека приемем, че редът на извикванията към методите на списъка е бил в последователност, т.е. get (5), size (), get (2). Така че, редът за проверка също трябва да бъде същият.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size(); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt());
В случай на грешна верига за проверка, Mockito изпраща изключение - т.е. проверка.VerificationInOrderFailure ”.
Така че в горния пример, ако променя реда на проверка чрез размяна на последните 2 реда, ще започна да получавам изключение VerificationInOrderFailure.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); when(mockedIntList.size()).thenReturn(100); InOrder mockInvocationSequence = Mockito.inOrder(mockedIntList); // Act int response = mockedIntList.get(5); int size = mockedIntList.size(); response = mockedIntList.get(2); // Assert mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList, times(1)).get(anyInt()); mockInvocationSequence.verify(mockedIntList).size();
(v) Проверете дали взаимодействието е възникнало поне / най-много пъти.
(да се) поне:
сортиране на балончета в c ++
Пример: atleast (3) - Проверява дали подиграваният обект е бил извикан / взаимодействал поне три пъти по време на теста. Така че всяко от взаимодействията 3 или по-големи от 3 трябва да направи проверката успешна.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atLeast(2)).get(anyInt());
В случай на грешки, т.е. когато действителните извиквания не съвпадат, се извежда същото изключение, както при съвпадението times (), т.е. проверка.TooLittleActualInvocations ”
б) най-много:
Пример: atmost (3) - проверява дали подиграваният обект е бил извикан / взаимодействал с поне три пъти по време на теста. Така че всяко от 0,1,2 или 3 взаимодействия с макета трябва да направи проверката успешна.
// Arrange when(mockedIntList.get(anyInt())).thenReturn(3); // Act int response = mockedIntList.get(5); response = mockedIntList.get(2); // Assert verify(mockedIntList, atMost(2)).get(anyInt()); verify(mockedIntList, atMost(2)).size();
# 2) Съпоставяне на аргументи
В горното извикване съвпаденията могат да се комбинират заедно с аргументите, за да се проверят аргументите, с които е бил извикан макетът.
- всеки ()
- Конкретни стойности - Проверете с конкретните стойности, когато аргументите са известни предварително.
- Други съвпадения на аргументи като - anyInt (), anyString () и т.н.
Съвети и трикове
# 1) Използване на Argument Capture по време на проверка
Проверката на Argument Capture обикновено е полезна, когато аргументът, използван от някакъв метод с прекъсване, не се предава директно чрез извикване на метод, а се създава вътрешно при извикване на тествания метод.
Това е по същество полезно, когато методът ви зависи от един или повече сътрудници, чието поведение е смазано. Аргументите, предадени на тези сътрудници, са вътрешен обект или изцяло нов набор от аргументи.
Проверката на действителния аргумент, с който биха били извикани сътрудниците, осигурява голяма увереност в кода, който се тества.
как да върна масив от низове в java -
Mockito предоставя ArgumentCaptor, който може да се използва с проверка и след това, когато се извика “AgumentCaptor.getValue ()”, можем да утвърдим действителния уловен аргумент срещу очаквания.
За да илюстрирате това, вижте примера по-долу:
В метода по-долу CalcuPrice е моделът с класа InventoryModel се създава вътре в тялото на метода, който след това се използва от InventoryService за актуализация.
Сега, ако искате да напишете тест, за да проверите с какъв аргумент е бил извикан inventoryService, можете просто да използвате ArgumentCaptor обект от клас InventoryModel клас.
Тестван метод:
public double calculatePrice(int itemSkuCode) { double price = 0; // get Item details ItemSku sku = itemService.getItemDetails(itemSkuCode); // update item inventory InventoryModel model = new InventoryModel(); model.setItemSku(sku); model.setItemSuppliers(new String[]{'Supplier1'}); inventoryService.updateInventory(model, 1); return sku.getPrice(); }
Тестов код: Погледнете стъпката за проверка, където е проверена inventoryService, обектът argumentCaptor е заменен с кой аргумент трябва да бъде съчетан.
След това просто заявете стойността, като извикате метода getValue () в обекта ArgumentCaptor.
Пример: ArgumentCaptorObject.getValue ()
public void calculatePrice_withValidItemSku_returnsSuccess() { // Arrange ItemSku item1 = new ItemSku(); item1.setApplicableDiscount(5.00); item1.setPrice(100.00); CustomerProfile customerProfile = new CustomerProfile(); customerProfile.setExtraLoyaltyDiscountPercentage(2.00); double expectedPrice = 93.00; // Arrange when(mockedItemService.getItemDetails(anyInt())).thenReturn(item1); ArgumentCaptor argCaptorInventoryModel = ArgumentCaptor.forClass(InventoryModel.class); // Act priceCalculator.calculatePrice(1234); // Assert verify(mockedItemService).getItemDetails(anyInt()); verify(mockedInventoryService).updateInventory(argCaptorInventoryModel.capture(), eq(1)); assertEquals(argCaptorInventoryModel.getValue().itemSku, item1);
Без ArgumentCaptor няма да има начин да се идентифицира с какъв аргумент е направено повикването за услуга. Най-доброто е да използвате „any ()“ или „any (InventoryModel.class)“, за да проверите аргументите.
# 2) Чести изключения / грешки при използване на съвпадения
Докато използвате Matchers, има определени конвенции, които трябва да се спазват, които, ако не се спазват, водят до изключение. Най-често срещаният, на който попаднах, е докато попивам и проверявам.
Ако използвате някакъв аргументMatchers и ако методът на заглушаване има повече от един аргумент (аргументи), тогава или всички аргументи трябва да бъдат споменати със съвпадения, в противен случай никой от тях не трябва да има съвпадения. Какво означава това?
Нека се опитаме да разберем това със сценарий (и след това пример за кода за този сценарий)
- Да предположим, че тестваният метод има подпис като -
concatenateString (String arg1, String arg2) - Сега, когато забивате - да предположим, че знаете стойността на arg1, но arg2 е неизвестен, затова решавате да използвате съвпадение на аргументи като - any () или anyString () и да посочите стойност за първия аргумент като някакъв текст „здравей“.
- Когато горната стъпка е изпълнена и тестът е изпълнен, тестът хвърля изключение, наречено „InvalidUseOfMatchersException“
Нека се опитаме да разберем това с пример:
Тестов код:
// Arrange when(a gMatcher.concatenateString('hello', anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
Тестван клас:
public class ArgMatcher { public String concatenateString(String arg1, String arg2) { return arg1.concat(arg2); } }
Когато горният тест бъде изпълнен, той се връща в „ InvalidUseOfMatchersException '
Сега, каква е причината за това изключение?
Това е забиването с използване на частични съвпадения и частично фиксиран низ, т.е. споменахме едно съвпадение на аргументи като „здравей“ и второ като anyString (). Сега има 2 начина да се отървете от този вид изключения (Също така имайте предвид, че това поведение се отнася както за настройките на Mock, така и за поведението).
# 1) Използвайте Argument Matches за всички аргументи:
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) Използвайте eq () като Argument Matcher, където аргументът е известен. Така че, вместо да посочвате аргумента като „здравей“, посочете го като „eq („ здравей “) и това трябва да направи ударенето успешно.
// Arrange when(argMatcher.concatenateString(anyString(), eq('world'))).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'world'); // Assert verify(argMatcher).concatenateString(anyString(), eq('world'));
Заключение
В тази статия видяхме как да използваме различни видове съвпадения, предоставени от Mockito.
Тук разгледахме най-широко използваните. За справка с пълния списък, документацията на Mockito Library е добър източник на справка.
Вижте нашия предстоящ урок, за да научите повече за частните, статичните и празните методи на подигравките.
Препоръчително четене
- Създаване на макети и шпиони в Mockito с примери за кодове
- Mockito Tutorial: Mockito Framework for Mocking in Unit Testing
- Видове рискове при софтуерни проекти
- Типове данни на Python
- Типове данни на C ++
- Топ 12 въпроса за интервю за Mockito (Подигравателно рамково интервю)
- Подигравка на частни, статични и невалидни методи с помощта на Mockito
- Видове наследяване в C ++