Application Test종류
。일반적으로Application은 아래의Application Test를 모두 수행.
System TestingorIntergration Testing
。완성된 전체 Application을 배포한 후Unit Test를 수행
▶Application을jar또는war파일로 build를 수행 후AWS등으로 배포한 후Unit Test를 수행.
Unit Testing
。Application code의 특정 개별구성요소의 단위로 독립적인Unit Test를 수행
▶Application의 특정Method,Class등의 단위로 독립적으로Unit Test를 수행.
Unit Testing:
。Application의 개별구성요소(Method,Class등 )단위로 독립적으로 Test를 수행하는 과정.
▶ Application의 개별구성요소의 예상되는 작동과 실제작동을 비교하면서 Test하는 과정으로 진행됨.
。 보통 수천개로 구성된 코드의 작은 단위를 독립적으로 Test하여 올바른 동작여부의 검증을 수행하여 Application에서 발생하는 버그를 조기에 검출이 목표.
。Method단위로Unit Testing중 bug 발생 시 어느 특정Method에 bug가 발생하는지 명확히 특정이 가능하여 bug fixing이 용이.
。코드 변경 시 자동으로 Test를 수행하도록 Test의 자동화 가능.
。Java의Unit Test Framework는JUnit과Mockito가 존재.
。실제 개발에서의Unit Test는 개발자중 한명이 실수로 코드 변경 시 코드가 지속적통합(CI) 방식으로Github Repository에Commit되자마자 전체적으로Unit Test를 수행하여 통과를 못해 발생한Error을 검출하여 개발자에게 전달하는 예방용도로 사용됨.
지속적 통합 (
CI:Continuous Integration) REST API-Versioning
。Versioning System에 대한 새로운 코드를 작성하는 등의 변경 사항을 정기적으로Repository에Commit하여 통합함으로써 모든 사람에게 동일 작업 기반을 제공
Java의Test Framework
src/test/java:
。Java Application의 전반적인Test code가 위치하는 디렉토리.
▶JUnit,Mockito등에 의해 수행되는Unit Test Code를 해당 Directory에 작성.
。Business Logic이 구현된src/main/java의 하위 package 경로와 동일해야한다.
。Test Code를 정의한Java Class파일은src/test의 package 하에서Test를 수행할Java Class파일과 동일한Package에 저장.
▶Test Code의 파일명은Class명Test로 정의.
JUnit:
。Java에서Unit Test를 실행하는 용도의Test Framework
▶Annotation을 선언하여 쉽게Test code를 작성 및Unit Test의 실행과 검증이 모두 가능.
。Spring에서의JUnit Test Method는@Test를 선언 및 반환값이void이며 , 매개변수를 가지지 않음.
▶@Test선언 시JUnit에서Test Method로 인식하여 자동으로 실행.
。JUnit Test Method는 순서에 상관없이 무작위로 실행됨
▶JUnit Annotation을 선언하여 초기화등의 이유로 우선적으로 실행되거나 Resource해제 등의 이유로 모든 Test가 마친 후 마지막에 실행될 특정Test Method를 선언할 수 있다.
JUnit기능
。Annotation(@Test등 )을 활용한Test code작성
。JUnit만 독립적으로 수행이 가능.
。Test 실행 후 결과 확인 후 검증이 용이
。여러개의 Test를 묶어서 한번에 실행이 가능.
。Exception발생의 Test가 가능
。Before / After Hook이 존재.
JUnitDependecy 추가<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <scope>test</scope> </dependency>。
junit-jupiter-api:JUnit 5에서Unit Test실행을 위한 Library
。scope=test:Unit Test범위를Test code에서만 적용을 정의.
JUit 5:
。JUnit Platform+JUnit Jupiter+JUnit Vintage의 모듈이 합쳐진 Framework.
▶ 단일Library가 아닌,Platform+Engine구조로 동작.
JUnit Platform:
。JUnit 5에서JUnit Jupiter와JUnit Vintage를 실행할 수 있도록 하는 Test Platform.
▶ 여러개의Test Engine을 동시에 실행이 가능.
JUnit Jupiter:
。Test를 실행하는JUnit 5의Test Engine
JUnit Vintage:
。Test를 실행하는JUnit 3 & 4의Test Engine
。JUnit 5로 전환 전에 작성된JUnit Test code를JUnit 5환경에서도 실행할 수 있도록 지원.
▶ 기존Test code는 계속 활용하면서 새로운JUnit 5의Test code는JUnit Jupiter를 통해서 작성하도록 설계.
JUnitAnnotation
。import org.junit.jupiter.api.*;를 통해 해당 package 내에 있는 모든 Annotation을 import.
@ExtendWith(특정Extension.class)
import org.junit.jupiter.api.extension.ExtendWith;
。JUnit 5에서Unit Test실행 시 특정 Extension을 추가할때Test Class에 선언하는 Annotation
ex )@ExtendWith(MockitoExtension.class)
@Test:
。Spring의Test Class파일에Test Method에 선언하는JUnitAnnotation
▶@Test선언 시JUnit에서Test Method로 인식하여 자동으로 실행.
。Test Method는 반환값이void이며 , 매개변수를 가지지 않음.
。JUnit 5에서는org.junit.jupiter.api.Testpackage에서 제공.
@BeforeAll:
。Test Class를 구성하는 모든Test Method를 실행하기 전 단 한번만 실행할Static Method에 선언.
▶Static Method에서만 선언이 가능하다.
▶ 전체 Test가 실행되기 전Resource 초기화(DB Connection,File load등 ) 시 사용.
▶ 반드시Static Method에 선언
@BeforeEach:
。Test Class를 구성하는 각각의Test Method를 실행할때마다 실행할 Method에 선언.
▶ 각각의Test Method별 초기화가 필요한 경우에 사용.
@AfterAll
。Test Class를 구성하는 모든Test Method를 실행한 후 단 한번만 실행할Static Method에 선언.
▶ 전체 Test가 끝난 후Resource해제(DB Connection종료 , log 정리 등 ) 시 사용.
@AfterEach:
。Test Class를 구성하는 각각의Test Method를 실행한 직후에 실행할 Method에 선언.
▶ 각각의Test Method실행 후 정리작업(DB Rollback,Resource해제 등 ) 수행 시 사용.import org.junit.jupiter.api.*; class MyMathTest { @Test void test1() { System.out.println("test 1"); } @Test void test2() { System.out.println("test 2"); } @AfterEach void test3(){ System.out.println("@AfterEach : 각각의 @Test Method 실행 후 작동"); } @BeforeEach void test4() { System.out.println("@BeforeEach : 각각의 @Test Method 실행 전 작동"); } // BeforeAll과 AfterAll이 선언된 TestMethod는 static을 선언해야한다. @BeforeAll static void test5(){ System.out.println("@BeforeAll : 처음 @Test Method를 실행 전 작동."); } @AfterAll static void test6(){ System.out.println("@AfterAll : 마지막 @Test Method를 실행 후 작동."); } }▶
@BeforeAll과@AfterAll이 선언된 Method는static을 선언해야한다.
JUnit AssertMethod
。Test Method에 설정할 검증목적의 특정 테스트조건을 정의하는 Method.
▶JUnit에 의한Unit Test중 해당assert method중 하나라도 실패 시Unit Test에 통과하지 못함.
。import static org.junit.jupiter.api.Assertions.*;를 통해 해당 package 내에 있는 모든 Method를 import.
assertEquals( 예측값, 실제값 , "실패메시지" ):
。Test를 수행할 Method의 실제반환값과 예측반환값을 설정하여 비교하는 Testing을 수행 후 두 값이 동일하면 성공 및 다른 경우 실패로 도출하여 판별.
。매개변수로서 반영되는 값의 모든Data type에 대해서는 구현되어있으므로type에 상관없이 모두 사용가능.
▶Wrapper Class로 구현된type( ex.Integer)까지 사용가능.
。 테스트 실패 시 메시지를 출력.@Test void testMyMath1() { MyMath myMath = new MyMath(); int actualvalue = myMath.calculateSum(1,2,3,4,5); assertEquals( 15 , actualvalue); }▶ 비교결과가 다를 경우 Test는 실패하여
Assertion Error발생.
assertNotEquals( 예측값, 실제값 , "실패메시지" )
。Test를 수행할 Method의 실제반환값과 예측반환값을 설정하여 비교하는 Testing을 수행 후 두 값이 다르면 성공 및 동일한 경우 실패로 도출하여 판별.
fail("실패 메시지"):
。사용자가 임의로Test수행 시 무조건 실패하도록 사용하는 목적의 Method.
▶ 테스트 실패 시 메시지를 출력.
assertTrue( Boolean , "실패메시지" )
。특정 조건이true를 반환하는지 검증하는 역할을 수행.
▶ Test 예상결과가true를 기대할 경우 사용.
。테스트 실패 시 메시지를 출력.List<String> todos = Arrays.asList("AWS" , "Azure" , "DevOps"); @Test void testContains(){ assertTrue( todos.contains( "AWS" ) , "포함하지 않습니다."); }
assertFalse( Boolean , "실패메시지" )
。특정 조건이false를 반환하는지 검증하는 역할을 수행.
▶ Test 예상결과가false를 기대할 경우 사용.
assertNull( Null , "실패메시지" )
。Null값을 반환하는지 검증하는 역할을 수행.
▶ Test 예상결과가Null을 기대할 경우 사용.
assertNotNull( Null이 아닌 값 , "실패메시지" )
。Null값을 반환하지 않는지 검증하는 역할을 수행.
▶ Test 예상결과가Null이 아닐경우를 기대할 경우 사용.
assertArraysEquals( 예측배열 , 실제배열 , "실패메시지" )
。JUnit에서 배열을 비교 시 사용하는Assert Method
▶ 2개의 배열이 동일한 요소값과 순서를 가지고 있는지 검사하며 다를 경우Unit Test실패.@Test void testIntArrayEquals() { int[] expected = new int[] {1, 2, 3}; int[] actual = new int[] {1, 2, 3}; assertArrayEquals(expected, actual); // 배열이 같으면 테스트 통과 }
Mockito:
。Application에서 특정 개별구성요소의 단위(Class등 )의Dependency Injection이 구현되어 의존성이 존재하는 객체에Dependency가 분리된상태로JUnit을 통한Unit Test를 수행하기위하여 가짜 Dependency 역할의Mock객체를 생성하여Unit Test를 수행하도록JUnit을 보조하는 역할의Mocking Framework
▶JUnit과 함께 사용되어 보조하는 역할로 활용.
。Dependency를 지닌 실제객체를 Test할 경우, 해당Dependency대상객체대리하는Mock객체( 가짜 )를 생성하여 실제Dependency객체와Dependency가 분리된상태로 독립적인Unit Test를 수행하게 하는 용도로 활용.
。Spring Boot에서JUnit과Mocking을 동시에 활용하여Dependency가 있는 실제객체 대신Mocking을 통한 대리용도의Mock객체를 생성하여JUnit을 통해 독립적인Unit Testing을 수행.
Mock:
。기존Stub의 역할을 대체하는 가짜 객체.
▶ Dependency를 분리한 특정 객체의Unit Testing이 수행되도록 보조.
▶Stub과 달리 원본객체에 수정이 발생하거나 반환값을 변경시에도 보다 더 유연하게 대처가 가능하며, 추가적으로Mock객체.verify()method를 활용 하여 특정 Method가 호출되었는지 검증이 가능하다.
。Mock객체는 실제 구현이 없는 Dummy 객체로서,Method호출 시 기본적으로Null을 반환.
▶when().thenReturn()을 사용하여 원하는 값을 반환하도록 구현 가능.
org.mockito.Mockito관련 기능
Mockito.anyInt():
。Mockito의Argument Matcher로서 , 어떤int값이든 허용하는 matcher.
▶ 매개변수로 어떤 정수값이 전달되더라도 일치하도록 설정
ex )when(listMock2.get(Mockito.anyInt())).thenReturn(3);
▶listMock2.get(0)호출시 3 도출.
mock( Dependency대상.class ):import static org.mockito.Mockito.mock;
。해당 Dependency대상의 역할을 가상으로 수행할Mock instance를 생성.
when( Mock객체.실행할 Method ):import static org.mockito.Mockito.when;
。Mock instance의 Dependency 대상 객체의 특정 Method가 실행 시 실행할 행동을 정의.
when( Mock객체.실행할 Method ).thenReturn(해당 Method가 반환값)
。Method가 실행 시 해당 Method의 반환값을 설정.
。when( Mock객체.실행할 Method ).thenReturn(1).thenReturn(2);으로 중복으로 설정 시 해당method를 첫번째 호출 시1, 두번째부터 호출 시 마지막값인2를 반환@Test void test2(){ // DataService interface의 Mock instance 생성 DataService dataServiceMock = mock(DataService.class); // Mock의 retrieveAllData() method 실행 시 반환값을 정의. when(dataServiceMock.retrieveAllData()).thenReturn(new int[] {1,2,3,4,5,6,7,8,9}); findMaxValue findMaxValue = new findMaxValue(dataServiceMock); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); }
org.mockito.Mockito관련 Annotation
。Test Class에JUnit의@ExtendWith(MockitoExtension.class)를 선언하여Mockito Extension을 구현 후 사용.
▶Annotation을 선언하여Mock instance를 생성하거나Mock instance의 의존성주입 수행 가능.
@Mock:
。특정 객체의Mock객체 생성 시 선언하는 Annotation.
▶Mock객체는 실제 구현이 없는 Dummy 객체로서,Method호출 시 기본적으로Null을 반환.
@InjectMocks
。@Mock으로 생성된Mock객체를Test대상객체에 의존성주입을 하는 역할의 Annotation@ExtendWith(MockitoExtension.class) class findMaxValueTest { // Mock 객체 생성 // DataService dataServiceMock = mock(DataService.class); 와 같은역할 수행 @Mock private DataService dataServiceMock; // dataServiceMock이 의존성 주입. // findMaxValue findMaxValue = new findMaxValue(dataServiceMock); 와 같은 역할 수행. @InjectMocks private findMaxValue findMaxValue; @Test void test3(){ when(dataServiceMock.retrieveAllData()).thenReturn(new int[] {1,2,3,4,5,6,7,8,9}); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); }
Stub:
。미리 정의된 행동을 수행하는 가짜 객체.
▶ Dependency를 분리한 특정 객체의Unit Testing이 수행되도록 보조.
。 특정 입력값에 대하여 정해진 반환값을 제공하여 고정된 응답이 필요할 때 사용.
▶ 테스트 중 실제 logic을 실행하는것이 아닌, 고정된 response를 반환.
。그러나, 원본 객체에 새로운 method가 추가되는 수정이 발생하거나 반환값을 변경할때마다 새로운Stub을 생성해야하는 번거로움이 존재하므로,Mock활용.import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*; class findMaxValueTest { @Test void test(){ findMaxValue findMaxValue = new findMaxValue(new DataServiceStub()); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); } } class DataServiceStub implements DataService{ @Override public int[] retrieveAllData(){ return new int[]{1,2,3,4,5,6,7,8,9}; } }。
DataService interfaceinstance가 구현되어 의존성이 존재하는 Class를 Test
。DataService interface의 역할을 가상으로 수행하기위한Stub생성 시 원본 interface를 상속하고 기본 Method를 구현한 Class를 구현.
▶Stub은 미리 정의된 행동을 수행하는 가짜 객체로서 해당 Method가 실행될 내용을 사전에 정의하여 정의된 행동을 수행하도록 설정.
MockitoDependency 추가<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency>
JUnit실습
。Intellij환경에서JUnit을 활용해보기.
JUnit 5Dependency 정의<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <scope>test</scope> </dependency>
src/testdirectory 생성 및 test폴더 설정.
。Project Directory 우클릭→Open Module Settings→Modules→Mark as에서Tests를 선택 후test폴더로 지정할 Package를 선택
▶Test 폴더가 지정된 경우 다음처럼 초록색 폴더Icon으로 지정된 것을 확인 가능.
src/main/하위Package에서Java Class생성 후JUnit Test를 수행할 Method 정의public class MyMath { int sum=0; // 가변 매개변수로 가져오기 public int calculateSum(int... params){ for(int i=0;i<params.length;i++){ sum+=params[i]; } return sum; } }
src/test/하위Package에Test Code를 정의할Java Test Class작성하기
。Test를 수행할Java Class의Class명을 우클릭 →Go To→Test를 통해src/testPackage 하에서src/main/하위Package와 동일한하위Package에Test Code를 정의하는 Class 생성.
▶src/testPackage에서 테스트를 수행할Java Class파일이 위치한src/main/하위Package의 동일한 Package 위치에Java Test Class파일이 생성.
。Test Code를 정의한Java Class파일은src/test의 package 하에서Test를 수행할Java Class파일과 동일한Package에 저장.
▶Test Code의 파일명은Class명Test로 정의.
Java Test Class파일에Test Code작성package com.wjdtn747.rest.webservices.juit_test.junittesting; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class MyMathTest { @Test void testMyMath1() { MyMath myMath = new MyMath(); // 정답 예측값 assertEquals( myMath.calculateSum(1,2,3,4,5) , 15 ); } @Test void testMyMath2() { MyMath myMath = new MyMath(); // 틀린 예측값 assertEquals( myMath.calculateSum(1,2,3,4,5) , 20 ); } }。
Test를 수행할Class instance를 생성 및 해당 instance의Method를 Test.
。Spring에서의JUnit Test Method는@Test를 선언 및 반환값이void이며 , 매개변수를 가지지 않음.
▶@Test선언 시JUnit에서Test Method로 인식하여 자동으로 실행.
。assertEquals( 예측값 , 실제값 ):
Test를 수행할 Method의 실제반환값과 예측반환값을 설정하여 비교하는 Testing을 수행 후 두 값이 동일하면 성공 및 다른 경우 실패로 도출하여 판별.
。 해당 코드를Test Class에 정의 후Run을 할 경우Method별로 예측 반환값과 실제 반환값을 비교하는 Testing을 수행 후 성공 및 실패 여부를 지시.
▶ 실제 개발에서의Unit Test는 개발자중 한명이 실수로 코드 변경 시 코드가 지속적통합(CI) 방식으로Github Repository에Commit되자마자 전체적으로Unit Test를 수행하여 통과를 못해 발생한Error을 검출하여 개발자에게 전달하는 예방용도로 사용됨.
지속적 통합 (CI:Continuous Integration) REST API-Versioning
。Versioning System에 대한 새로운 코드를 작성하는 등의 변경 사항을 정기적으로Repository에Commit하여 통합함으로써 모든 사람에게 동일 작업 기반을 제공.
Mockito실습
MockitoDependency 정의<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <scope>test</scope> </dependency>
Mockito를 활용한 Test를 수행할 Dependecy가 존재하는Java Class생성 후 Method 구현
。src/main/java/하위패키지에 위치// src/main/java/com/wjdtn747/rest/webservices/mockito_test/findMaxValue.java interface DataService{ int[] retrieveAllData(); } public class findMaxValue { DataService dataService; // Constructor-based Dependency Injection findMaxValue(DataService dataService){ this.dataService = dataService; } public int findMaxValueFromData() { int[] data = dataService.retrieveAllData(); int maxvalue = Integer.MIN_VALUE; // 초기값 설정 for (int value : data) { // data 배열의 요소를 하나씩 추출하여 value 변수로 인가 if (value > maxvalue) { maxvalue = value; } } return maxvalue; } }。 해당 Class에서
DataService interface의 instance에 생성자의존성주입을 수행하므로dependency가 구현됨.
▶ 의존성주입을 구현하지 않으면 해당 instance에서java.lang.NullPointerException오류 발생.
integer.MIN_VALUE:
。Java의 정수형int type이 가질 수 있는 가장 작은값을 지시하는 상수.
Stub으로Java Class Method를 Testing하는Java Test Class생성 및Test Method구현
。src/main/java/하위패키지경로의Java Class와 동일한src/main/test의 하위package경로에Test Class생성 후Test Method생성.
。Test Method에서Java Classinstance 생성 시 해당 Class의 의존성주입으로 인해 생성자에DataService interface의 instance를 넣어야하므로,DataService interface역할을 가상으로 수행할Stub을 생성.// src/test/java/com/wjdtn747/rest/webservices/mockito_test/findMaxValueTest.java import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*; class findMaxValueTest { @Test void test(){ findMaxValue findMaxValue = new findMaxValue(new DataServiceStub()); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); } } class DataServiceStub implements DataService{ @Override public int[] retrieveAllData(){ return new int[]{1,2,3,4,5,6,7,8,9}; } }。
DataService interface의 역할을 가상으로 수행하기위한Stub생성 시 원본 interface를 상속하고 기본 Method를 구현한 Class를 구현.
▶Stub은 사전에 고정된 정의된 행동을 수행하는 가짜 객체로서 해당 Method가 실행될 내용을 사전에 정의하여 정의된 행동을 수행하도록 설정.
Mock으로Java Class Method를 Testing하는Test Method구현
。mock( Dependency대상.class )으로 해당DataService interface의 역할을 가상으로 수행할Mock instance를 생성
。when( Mock객체.실행할 Method ).thenReturn(해당 Method가 반환값)을 통해DataService interface에 구현 MethodretrieveAllData()를 실행 시 반환값을 설정.
▶Mock은 dummy객체로 구현하지 않으면Null을 반환.
▶stub의 다른 반환값을 설정하기위해서Class를 하나 더 생성해야하는 불편함을 해결할 수 있다.@Test void test2(){ // DataService interface의 Mock instance 생성 DataService dataServiceMock = mock(DataService.class); // Mock의 retrieveAllData() method 실행 시 반환값을 정의. when(dataServiceMock.retrieveAllData()).thenReturn(new int[] {1,2,3,4,5,6,7,8,9}); findMaxValue findMaxValue = new findMaxValue(dataServiceMock); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); }
- Annotation으로 구현된
Mock으로Java Class Method를 Testing하는Test Method구현@ExtendWith(MockitoExtension.class) class findMaxValueTest { // Mock 객체 생성 // DataService dataServiceMock = mock(DataService.class); 와 같은역할 수행 @Mock private DataService dataServiceMock; // dataServiceMock이 의존성 주입. // findMaxValue findMaxValue = new findMaxValue(dataServiceMock); 와 같은 역할 수행. @InjectMocks private findMaxValue findMaxValue; @Test void test3(){ when(dataServiceMock.retrieveAllData()).thenReturn(new int[] {1,2,3,4,5,6,7,8,9}); int result = findMaxValue.findMaxValueFromData(); assertEquals(9,result); }。
@Mock으로DataService Interface의Mock instance생성.
。@InjectMocks로 테스트대상 객체인findMaxValueinstance에Mock instance를 의존성주입.
。@ExtendWith(MockitoExtension.class)를Test Class에 선언하여Mockito Annotation을 사용할 수 있도록 설정.
Mockito실습
- 하나의 반환값이 필요한 경우
import java.util.List; import static org.junit.Assert.*; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class findMaxValueTest { // mock(List.class) 와 동일 @Mock List listMock; @Test void test(){ // Mock객체.size() 요청 시 Null이 아닌 3을 반환하도록 설정. when(listMock.size()).thenReturn(3); assertEquals(3, listMock.size()); } }
- 여러개의 반환값이 필요한 경우
import java.util.List; import static org.junit.Assert.*; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class findMaxValueTest { @Mock List listMock2; @Test void test2(){ when(listMock2.get(0)).thenReturn(3).thenReturn(4).thenReturn(5); assertEquals(null, listMock2.get(1)); assertEquals(3, listMock2.get(0)); assertEquals(4, listMock2.get(0)); assertEquals(5, listMock2.get(0)); assertEquals(5, listMock2.get(0)); } }。각각 반복해서
listMock2.get(0)호출 시3,4,5,5도출.
。listMock2.get(1)호출 시nullreturn.
▶when(listMock2.get(Mockito.anyInt())).thenReturn(3).thenReturn(4).thenReturn(5);을 설정할 경우,listMock2.get(1)호출 시3을 return.