different types matchers provided mockito
배열 자바의 내용을 인쇄하는 방법
Mockito의 다양한 유형의 매처 소개.
Mockito의 모의와 스파이 이전 튜토리얼에서 자세히 설명했습니다. Mockito 교육 시리즈 .
Matchers는 무엇입니까?
Matchers는 특정 입력 (및 또는 출력) 대신에 어떤 스텁 / 스파이가 휴지 될 수 있고 스텁 호출을 확인할 수 있는지에 따라 입력 / 출력의 범위 / 유형을 지정하는 정규식 또는 와일드 카드와 같습니다.
모든 Mockito 매처는‘ Mockito ' 정적 클래스.
Matchers는 강력한 도구로, 사용 사례 또는 시나리오에 따라 인수 입력을 특정 값에 대한 일반 유형으로 언급하여 스텁을 설정하고 스텁에서 호출을 확인하는 간단한 방법을 사용할 수 있습니다.
학습 내용 :
Mockito의 매처 유형
Mockito에는 크게 두 가지 유형의 매 처가 있습니다. 또는 사용 측면에서 matcher는 아래 두 범주에 사용할 수 있습니다.
- 스텁 설정 중 인수 매처
- 스텁에 대한 실제 호출을 검증하기위한 검증 매처
두 가지 유형의 Matcher (예 : Argument 및 Verification)에 대해 Mockito는 방대한 matcher 세트를 제공합니다 (클릭 여기 매처의 전체 목록을 얻으려면).
인수 매처
가장 널리 사용되는 항목은 다음과 같습니다.
아래의 모든 항목에 대해 IntegerList 테스트를 고려해 보겠습니다.
final List mockedIntList = mock(ArrayList.class);
#1) any () – 모든 객체 (널 포함)를 허용합니다.
when (mockedIntList.get( any ())).thenReturn(3);
#두) 모두 (자바 언어 클래스) –
예 : any (ClassUnderTest.class) – 이것은 any ()의보다 구체적인 변형이며 템플릿 매개 변수로 언급 된 클래스 유형의 객체 만 허용합니다.
when (mockedIntList.get( any (Integer.class))).thenReturn(3);
#삼) anyBoolean (), anyByte (), anyInt (), anyString (), anyDouble (), anyFloat (), anyList () 등 – 모두 해당 데이터 유형의 모든 객체와 null 값을 허용합니다.
when (mockedIntList.get( any Int())).thenReturn(3);
# 4) 특정 인수 – 실제 인수가 미리 알려진 경우, 일반 인수 유형에 비해 더 많은 신뢰를 제공하므로 항상 사용하는 것이 좋습니다.
예:
when(mockedIntList.get(1)).thenReturn(3);
검증 매처
아니오와 같은 것을 기대 / 주장 할 수있는 몇 가지 전문 매 처가 있습니다. 모의에 대한 호출.
아래의 모든 matcher에 대해 이전에 사용한 것과 동일한 예제 목록을 고려해 보겠습니다.
final List mockedIntList = mock(ArrayList.class);
# 1) 모의 호출
(나는) 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인지 확인하려면 times () 매처의 인수로 값을 1에서 0으로 변경하면됩니다.
//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) 모의 상호 작용 순서 확인 – 모의 개체에 대한 메서드가 호출 된 순서를 확인하려는 경우 특히 유용합니다.
예: 테스트에서 데이터베이스 업데이트가 발생한 순서를 확인해야하는 데이터베이스와 같은 작업입니다.
이를 예제로 설명하려면 – 동일한 예제 목록을 계속 진행하겠습니다.
이제 list 메서드에 대한 호출 순서가 순서대로 있다고 가정합니다. 즉, 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에서 예외가 발생합니다. validation.VerificationInOrderFailure ”.
따라서 위의 예에서 마지막 두 줄을 교환하여 확인 순서를 변경하면 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) 상호 작용이 최소한 / 최대 횟수 발생했는지 확인합니다.
(에) 적어도:
예: atleast (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 () 일치 자에서와 동일한 예외가 발생합니다. validation.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) 검증 중 인수 캡처 사용
인수 캡처 확인은 일반적으로 일부 스텁 메서드에서 사용하는 인수가 메서드 호출을 통해 직접 전달되지 않고 테스트중인 메서드가 호출 될 때 내부적으로 생성되는 경우 유용합니다.
편안한 웹 서비스 자바에 대한 인터뷰 질문
이것은 당신의 방법이 행동이 스텁 된 한 명 이상의 협력자에게 의존하는 경우에 본질적으로 유용합니다. 이러한 공동 작업자에게 전달 된 인수는 내부 개체이거나 완전히 새로운 인수 집합입니다.
공동 작업자가 호출되었을 실제 인수를 검증하면 테스트중인 코드에 대한 많은 확신이 보장됩니다.
Mockito는 검증과 함께 사용할 수있는 ArgumentCaptor를 제공하고 'AgumentCaptor.getValue ()'가 호출되면 예상되는 인수에 대해 실제 캡처 된 인수를 주장 할 수 있습니다.
이를 설명하기 위해 아래 예를 참조하십시오.
아래 메서드에서 calculatePrice는 InventoryModel 클래스가있는 모델이 메서드 본문 내부에 생성 된 다음 업데이트를 위해 InventoryService에서 사용되는 모델입니다.
이제 inventoryService가 호출 된 인수를 검증하는 테스트를 작성하려면 InventoryModel 클래스 유형의 ArgumentCaptor 객체를 사용하면됩니다.
테스트중인 방법 :
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 오브젝트가 일치해야하는 인수로 대체됩니다.
그런 다음 ArgumentCaptor 객체에서 getValue () 메서드를 호출하여 값을 지정하면됩니다.
예: 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를 사용하는 동안 따라야 할 특정 규칙이 있으며, 따르지 않으면 예외가 발생합니다. 내가 만난 가장 일반적인 것은 스터 빙 및 확인 중입니다.
argumentMatchers를 사용하고 있고 stubbed 메서드에 둘 이상의 인수가있는 경우 모든 인수를 matcher와 함께 언급해야합니다. 그렇지 않으면 해당 인수에 matcher가 없어야합니다. 자, 이것은 무엇을 의미합니까?
시나리오를 통해이를 이해해 보겠습니다 (이 시나리오의 코드 샘플).
- 테스트중인 메서드에 다음과 같은 서명이 있다고 가정합니다.
concatenateString (문자열 arg1, 문자열 arg2) - 이제 스터 빙 할 때 – arg1의 값을 알고 있지만 arg2는 알 수 없으므로 any () 또는 anyString ()과 같은 인수 매처를 사용하고 일부 텍스트 'hello'와 같은 첫 번째 인수의 값을 지정하기로 결정했다고 가정합니다.
- 위의 단계가 구현되고 테스트가 실행되면 테스트에서 '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 '
자,이 예외의 이유는 무엇입니까?
부분 매처와 부분 고정 문자열을 사용하는 스터 빙입니다. 즉, 하나의 인수 매처를 'hello'로, 두 번째 인자를 anyString ()으로 언급했습니다. 이제 이러한 종류의 예외를 제거하는 두 가지 방법이 있습니다 (또한이 동작은 Mock 설정과 동작 모두에 적용됨).
# 1) 모든 인수에 대해 인수 매처 사용 :
// Arrange when(a gMatcher.concatenateString(anyString(), anyString())).thenReturn('hello world!'); // Act String response = argMatcher.concatenateString('hello', 'abc'); // Assert verify(argMatcher).concatenateString(anyString(), anyString());
# 2) 인수가 알려진 Argument Matcher로 eq ()를 사용합니다. 따라서 인수를 'hello'로 지정하는 대신 'eq ('hello ')로 지정하면 스터 빙이 성공적으로 수행됩니다.
좋은 무료 음악 다운로더가 뭐야
// 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 문서가 좋은 참고 자료입니다.
Mocking의 Private, Static 및 Void 메서드에 대해 자세히 알아 보려면 다가오는 자습서를 확인하십시오.