Mockito 시 뮬 레이 션 으로 자바 유닛 테스트 진행
홈 페이지:https://site.mockito.org/
Mockito is a mocking framework, JAVA - based library that is used for effective unit testing of JAVA applications. Mockito is used to mock interfaces so that a dummy functional can be added to a mock interface that can be used in unit testing.Mockito 는 유닛 테스트 에서 허구 적 인 방법 을 사용 할 수 있 도록 인 터 페 이 스 를 모 의 할 수 있다.
왜 시 뮬 레이 션 이 필요 합 니까?유닛 테스트 의 생각 은 우리 가 의존 을 테스트 하지 않 고 코드 를 테스트 해 야 한 다 는 것 이다.때때로 우 리 는 의지 하고 싶 지 않 거나 의지 할 준비 가 되 지 않 았 다 고 말 할 때 우 리 는 시 뮬 레이 션 이 필요 하 다.
기본 용법
mock()
/ @Mock
: 시 뮬 레이 션 생 성when()
/ given()
시 뮬 레이 션 행 위 를 지정 합 니 다 (방법) null
, 0
값 또는 false
등 입 니 다.get(int)
방법 은 매개 변수 가 각각 0
과 1
일 때의 서로 다른 행 위 를 할 수 있다.spy()
/ @Spy
: 일부 시 뮬 레이 션 을 실현 하면 진정한 방법 은 호출 되 지만 stubbing 과 verify @InjectMocks
: 자동 주입 @Spy
또는 @Mock
주해 의 속성 verify()
: 방법 이 호출 되 었 는 지 검증 하고 몇 번 호출 되 었 습 니 다.any()
@Captor
통 해 캡 처 할 수 있 습 니 다 구체 적 인 참조:https://static.javadoc.io/org.mockito/mockito-core/2.22.0/org/mockito/Mockito.html
여기에서 maven 을 통 해 구축:
junit
junit
4.12
test
org.mockito
mockito-core
2.22.0
test
1. 방법 이 호출 되 었 는 지 확인 하기 위해 verify 를 사용 합 니 다.
import org.junit.Test;
import java.util.List;
import static org.mockito.Mockito.*;
public class TestRunner {
@Test
public void Test1() {
//
List mockedList = mock(List.class);
//
mockedList.add("one");
mockedList.clear();
// ,
verify(mockedList).add("one");
verify(mockedList).clear();
}
}
2. stubbing 존 근 을 어떻게 사용 합 니까?
@Test
public void Test2() {
// ,
LinkedList mockedList = mock(LinkedList.class);
// stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());
// first
System.out.println(mockedList.get(0));
// java.lang.RuntimeException
System.out.println(mockedList.get(1));
// "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));
}
3. 매개 변수 일치
예 를 들 어 우 리 는
anyInt()
를 사용 하여 임의의 정수 유형 과 일치 할 수 있다.더 많은 내장 matcher 와 사용자 정의 matcher 를 참조 하 십시오:https://static.javadoc.io/org.mockito/mockito-core/2.22.0/org/mockito/ArgumentMatchers.html @Test
public void Test3() {
// ,
LinkedList mockedList = mock(LinkedList.class);
// stubbing , anyInt()
when(mockedList.get(anyInt())).thenReturn("element");
// element
System.out.println(mockedList.get(999));
// ,
verify(mockedList).get(anyInt());
}
4. 검증 방법 이 호출 된 횟수
@Test
public void Test4() {
// ,
LinkedList mockedList = mock(LinkedList.class);
// mock
mockedList.add("once");
mockedList.add("twice");
mockedList.add("twice");
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
//
verify(mockedList).add("once");
verify(mockedList, times(1)).add("once");
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");
//
verify(mockedList, never()).add("never happened");
//
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("three times");
verify(mockedList, atMost(5)).add("three times");
}
5. 검증 방법의 호출 순서
@Test
public void Test5() {
List singleMock = mock(List.class);
// mock
singleMock.add("was added first");
singleMock.add("was added second");
// InOrder
InOrder inOrder = inOrder(singleMock);
// "was added first", "was added second"
inOrder.verify(singleMock).add("was added first");
inOrder.verify(singleMock).add("was added second");
}
6. @ Mock 주석 사용 하기
@Mock List mockedList;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void Test6() {
//
mockedList.add("one");
mockedList.clear();
// ,
verify(mockedList).add("one");
verify(mockedList).clear();
}
7. stubbing 캐 시 루트 를 사용 하여 연속 호출 을 모 의 합 니 다.
@Test
public void Test7() {
//
List mockedList = mock(List.class);
when(mockedList.get(anyInt()))
.thenThrow(new RuntimeException())
.thenReturn("foo");
// ,
mockedList.get(1);
// , foo
System.out.println(mockedList.get(1));
}
이렇게 사용 할 수 있 습 니 다:
when(mock.someMethod("some arg")).thenReturn("one", "two", "three");
8. 콜백 리 셋 이 있 는 stubbing 캐 시 를 사용 합 니 다.@Test
public void Test8() {
//
List mockedList = mock(List.class);
when(mockedList.get(anyInt())).thenAnswer(
new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Object mock = invocation.getMock();
return "called with arguments: " + Arrays.toString(args);
}
});
// "called with arguments: [1]"
System.out.println(mockedList.get(1));
}
9. doReturn (), doThrow (), doAnswer (), doNothing (), doCallRealMethod () 를 사용 하여 빈 방법 void method
@Test
public void Test9() {
//
List mockedList = mock(List.class);
doThrow(new RuntimeException()).when(mockedList).clear();
// RuntimeException:
mockedList.clear();
}
10. 진짜 대상 에서 스파이
when you use the spy then the real methods are called (unless a method was stubbed). 스파이 를 사용 할 때 실제 대상 의 방법 은 stubbing 을 사용 하지 않 는 한 호출 됩 니 다. 예 를 들 어
when()...
@Test
public void Test10() {
List list = new LinkedList();
List spy = spy(list);
//using the spy calls *real* methods
spy.add("one");
spy.add("two");
// one
System.out.println(spy.get(0));
// 2
System.out.println(spy.size());
verify(spy).add("one");
verify(spy).add("two");
}
11. 부분 시 뮬 레이 션 실현
@Test
public void Test11() {
//
List mockedList = mock(LinkedList.class);
// ,
when(mockedList.size()).thenCallRealMethod();
System.out.println(mockedList.size());
}
12. Mock 초기 화
reset(mock);
방법 을 통 해 이전에 설 치 된 stubbing 을 초기 화 합 니 다.예시
만약 에 우리 가 계산기 프로그램
CalculatorApplication
을 테스트 해 야 한다 고 가정 하지만 이 프로그램 은 CalculatorService
에 의존 하여 구체 적 인 계산 과정 을 실현 한다.코드 는 다음 과 같 습 니 다:public interface CalculatorService {
public double add(double input1, double input2);
public double subtract(double input1, double input2);
public double multiply(double input1, double input2);
public double divide(double input1, double input2);
}
public class CalculatorApplication {
private CalculatorService calcService;
public void setCalculatorService(CalculatorService calcService) {
this.calcService = calcService;
}
public double add(double input1, double input2) {
return calcService.add(input1, input2);
}
public double subtract(double input1, double input2) {
return calcService.subtract(input1, input2);
}
public double multiply(double input1, double input2) {
return calcService.multiply(input1, input2);
}
public double divide(double input1, double input2) {
return calcService.divide(input1, input2);
}
}
문제 가 생 겼 다. 테스트 할 때 우 리 는
CalculatorService
이 인터페이스의 구체 적 인 실현 류 가 없 을 것 이다. 예 를 들 어 CalculatorServiceImpl
.따라서 우 리 는 테스트 할 때 이 인터페이스의 행동 을 모 의 해 야 한다.이때 우 리 는 mockito 를 사용 하여 행동 을 모 의 한다.
mockito 는 주석 을 통 해 사용 할 수 있 습 니 다:
CalculatorService
: 테스트 러 너 지정 @RunWith(MockitoJUnitRunner.class)
: Mark a field on which injection should be performed. 변 수 를 표시 합 니 다. 이 변 수 는 Mock 에 주 입 됩 니 다.예 를 들 어 @InjectMocks
는 하나의 CalculatorApplication
실현 에 주입 된다.CalculatorService
에서 하나의 CalculatorApplication
방법 을 정의 하여 주입 해 야 합 니 다.set
: Mark a field as a mock. 변 수 를 표시 합 니 다. 이 변 수 는 Mock 입 니 다.예 를 들 어 @Mock
.CalculatorService
를 통 해 이 Mock 의 행동 을 모 의 할 수 있다.예 는 다음 과 같다.
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class Mockito_Test {
@InjectMocks
CalculatorApplication calculatorApplication = new CalculatorApplication();
@Mock
CalculatorService calcService;
@Test
public void testAdd() {
// CalculatorService
when(calcService.add(10.0, 20.0)).thenReturn(30.00);
//
Assert.assertEquals(calculatorApplication.add(10.0, 20.0), 30.0, 0);
}
}
Mockito 원리
참고: 리 버스 모드 의 클래식 - Mockito 디자인 분석
우선, Mock 대상 이라는 것 은 본질 적 으로 프 록 시 모델 의 응용 이라는 것 을 알 아야 한다.프 록 시 모드 는 실제 대상 앞에서 프 록 시 대상 을 제공 하고 모든 실제 대상 에 대한 호출 은 프 록 시 대상 을 거 친 다음 에 프 록 시 대상 이 상황 에 따라 해당 하 는 처 리 를 결정 한다. 프 록 시 대상 은 자신의 처 리 를 직접 할 수도 있 고 실제 대상 에 대응 하 는 방법 을 사용 할 수도 있다. 프 록 시 대상 은 호출 자 에 게 투명 할 수도 있다.불투명 할 수도 있어.
Mockito 는 자바 가 제공 하 는 Dynamic Proxy API 로 구현 된다.자바 의 동적 에이전트 에 대해 서 는 자바 동적 대 리 를 참조 하 십시오.
Mockito 는 본질 적 으로 프 록 시 대상 호출 방법 전에 Stubbing 방식 으로 반환 값 을 설정 한 다음 에 실제 호출 할 때 프 록 시 대상 으로 미리 설 정 된 반환 값 을 되 돌려 줍 니 다.
다음 코드 를 살 펴 보 겠 습 니 다.
List mockedList = mock(List.class);
// mock - get 0 , "first"
when(mockedList.get(0)).thenReturn("first");
자바 의 프로그램 호출 은 스 택 형식 으로 이 루어 집 니 다.
when
방법 when()
방법 에 대한 호출 은 보이 지 않 습 니 다.mockedList.get(0)
받 을 수 있 는 것 은 when()
의 반환 값 뿐이다.그래서 위의 코드 도 다음 과 같다.// stubbing
Object ret = mockedList.get(0);
when(ret).thenReturn("first");
mockedList.get(0)
방법의 소스 코드 를 보 세 요.public OngoingStubbing when(T methodCall) {
MockingProgress mockingProgress = ThreadSafeMockingProgress.mockingProgress();
mockingProgress.stubbingStarted();
OngoingStubbing stubbing = mockingProgress.pullOngoingStubbing();
if (stubbing == null) {
mockingProgress.reset();
throw Reporter.missingMethodInvocation();
} else {
return stubbing;
}
}
when()
인터페이스 에 어떤 방법 이 있 는 지 보 세 요.public interface OngoingStubbing {
OngoingStubbing thenReturn(T var1);
OngoingStubbing thenReturn(T var1, T... var2);
OngoingStubbing thenThrow(Throwable... var1);
OngoingStubbing thenThrow(Class extends Throwable> var1);
OngoingStubbing thenThrow(Class extends Throwable> var1, Class... var2);
OngoingStubbing thenCallRealMethod();
OngoingStubbing thenAnswer(Answer> var1);
OngoingStubbing then(Answer> var1);
M getMock();
}
mock 대상 의 모든 방법 은 최종 적 으로
OngoingStubbing
의 MockHandlerImpl
방법 으로 처리 되 며, 일부 코드 는 다음 과 같다.OngoingStubbingImpl ongoingStubbing = new OngoingStubbingImpl(this.invocationContainer);
ThreadSafeMockingProgress.mockingProgress().reportOngoingStubbing(ongoingStubbing);
StubbedInvocationMatcher stubbing = this.invocationContainer.findAnswerFor(invocation);
StubbingLookupNotifier.notifyStubbedAnswerLookup(invocation, stubbing, this.invocationContainer.getStubbingsAscending(), (CreationSettings)this.mockSettings);
Object ret;
if (stubbing != null) {
stubbing.captureArgumentsFrom(invocation);
try {
ret = stubbing.answer(invocation);
} finally {
ThreadSafeMockingProgress.mockingProgress().reportOngoingStubbing(ongoingStubbing);
}
return ret;
} else {
ret = this.mockSettings.getDefaultAnswer().answer(invocation);
DefaultAnswerValidator.validateReturnValueFor(invocation, ret);
this.invocationContainer.resetInvocationForPotentialStubbing(invocationMatcher);
return ret;
}
handle
호출 의 기본 형식 은 when
이다. 이때 when(mock.doSome())
는 위의 문 구 를 촉발 시 킬 수 있다. mock.doSome()
는 한 방법 에 대해 말뚝 을 박 는 포장 을 하고 있다 고 밝 혔 다. OngoingStubbingImpl
는 한 mock 대상 의 집사 에 해당 하 며 mock 대상 방법의 호출 을 기록 하고 있다.인용: Mockito Tutorial 반 모드 의 고전 - Mockito 디자인 분석 Mockito 소스 코드 분석
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.