[java]Mockito 기본 설명

JAVA 2017. 5. 24. 18:36 |

Junit + Mockito


Junit 의 mock 중에 많이 사용되고 업데이트가 잘 이루어지고 있는 것에는 EasyMock, JMock, Mockito 가 있는데

이중 Mockito가 가장 간결한 코드로 테스트를 할 수 있다. 


verify() 

verify()을 이용하여 mock 객체에 대한 원하는 메소드가 특정조건으로 실행되었는지 검증할 수 있다.

mock 작업이 수행되었는지 검증한다. verify(T mock).method();

// mock
List mockedList = mock(List.class);

// mock 사용하기
mockedList.add("one");
mockedList.clear();

// verification
verify(mockedList).add("one");
verify(mockedList).clear();


VerificationMode의 값을 리턴해 주는 메소드는 다섯가지가 있다. 

verify(T mock, VerificationMode mode).method()

----------------------------------------------------------------------------

atLeastOnece();  적어도 한번 수행했는지 검증

atLeast(int n);    적어도 n 번 수행 했는지 검증

times(int n);      무조건 n번 수행했는지 검증 (n보다 크거나 작으면 오류로 간주)

atMost(int n);    최대한 n 번 수행했는지 검증

never();            수행되지 않았는지 검증(수행했으면 오류로 간주)

@Test
public void verifyTest() {
@SuppressAjWarnings("unchecked")
List<String> testMock = mock(ArrayList.class);
testMock.add("1");
testMock.add("2");
testMock.add("3");

// add()가 최소한 1번 이상 호출되었는지 검증
verify(testMock, atLeastOnce()).add(anyString());
// add()가 최소한 3번 이상 호출되었는지 검증
verify(testMock, atLeast(3)).add(anyString());
// add()가 최대한 3번 이하 호출되었는지 검증

verify(testMock, atMost(3)).add(anyString());
// add() 3번 호출되었는지 검증

verify(testMock, times(3)).add(anyString());


verify(testMock, times(1)).add("1"); // add("1") 1번 호출되었는지 검증

verify(testMock, times(1)).add("2"); // add("2") 1번 호출되었는지 검증

verify(testMock, times(1)).add("3"); // add("3") 1번 호출되었는지 검증


// add("4")가 수행되지 않았는지를 검증
verify(testMock, never()).add("4");

InOrder inOrder = inOrder(testMock); //mock 순서 다르게 verify 정의하면 오류난다.

inOrder.verify(testMock).add("1"); //순서 알수있음
inOrder.verify(testMock).add("2"); //순서 알수있음
inOrder.verify(testMock).add("3"); //순서 알수있음

}



when()

제대로 된 mock의 역할을 수행하기 위해서는 원하는 값을 리턴하는 기능도 제공되어야한다.

그럴때 사용하는 메소드가 when이다. when()메소드는 Mock이 감싸고 있는 메소드가 호출되었을 때 ,Mock객체의 메소드(행위)를 호출 선언할때 사용한다.

when() 메소드는 OngoingStubbing 이라는 인터페이스를 리턴한다.


OngoingStubbing 의 메소드

thenAnswer(Answer<?> answer): Answer라는 인터페이스를 구현하며, 원하는 작업을 수행 할 수 있다.

  • thenCallRealMethod(): 해당 메소드가 구현되어 있다면, 실제 메소드를 호출한다.
  • thenReturn(T value): 지정한 값을 리턴한다.
  • thenReturn(T value, T... values): 지정되어 있는 값을 순차적으로 리턴한다.
  • thenThrow(java.lang.Throwable... throwables):  예외를 야기시키는 Throwable 객체를 지정한다. 


@RunWith(MockitoJUnitRunner.class)
junit테스트 사용시 Mockito에서 제공하는 목객체를 사용하기위해 위와같이 어노테이션을 테스트 클래스위에 정의해주면 된다.(목객체 생성할 특정 빈이나 객체가 없다면 목객체는 필요없다.)

@RunWith(MockitoJUnitRunner.class)
public class UserTest{

}


@Mock
mock 인스턴스를 생성하여 목객체를 만들었는데 @mock 어노테이션을 이용해서 mock 객체 생성한다.
User user = mock(ArrayList.class);

위 코드를 아래처럼 사용하면 목 객체 생성. 

@Mock
private User user;



@injectMocks
mockito 에서는 injectMocks 어노테이션을 제공하는데 @Mock,@Spy 이 붙은 목객체를 자신의 멤버 클래스와 일치하면 주입시킨다.  
쉽게 말해 실제 테스트할 클래스가 @injectMocks어노테이션을 사용해 목객체를 생성한다.
테스트할 클래스 안에 또 다른 객체를 생성해야된다면 해당 객체를 @Mock 사용하여 목객체 생성하여 테스트한다.
예제를 보자.

public class AuthService{
private com.neowiz.nsis.mob.web.AuthDao dao;
// some code...
public boolean isLogin(String id){
boolean isLogin = dao.isLogin(id);
if( isLogin ){
// some code...
}
return isLogin;
}
}
public class AuthDao {
public boolean isLogin(String id){ //some code ... }
}

@Mock

AuthDao dao;

@InjectMocks
AuthService service;

@Test
public void example(){
MockitoAnnotations.initMocks(this);
when(dao.isLogin(eq("JDM"))).thenReturn(true);
assertTrue(service.isLogin("JDM") == true);
assertTrue(service.isLogin("ETC") == false);
}




@Before @After
메소드위에 선언되면 해당 테스트 클래스 안에서 메소드들이 테스트되기 전,후에 초기화를 실행하는 어노테이션이다.
private ModelAndView mnv;

@Before
public void setUp() throws Exception {
mnv = new ModelAndView();
}
mvn 객체는 테스트하기전에 초기화되서 매번 정의할 필요없이 테스트 메소드에서 사용 가능 하다. 



assertThat() - hamcrest 
junit 테스트시에 다양한 조건의 match rule 을 손쉽게 작성하고 테스트 할수 있다.(가독성이 더 좋음!!)
assertThat() 뒤에 하나 또는 여러개의 matchers를 사용하여 테스트결과를 확인할 수 있다.


public class CalculatorTest {
Calculator calculator = new Calculator();
@Test
public void testAdd() {
int result = calculator.add(4, 6);
assertThat(result, is(10));
}
}

junit 기본매쳐 링크 클릭하면 된다.








'JAVA' 카테고리의 다른 글

java StringTokenizer  (0) 2015.12.29
Posted by 양승아
: