본문 바로가기
Java

[Java] Mockito 사용법 (4) - 검증 (Verify)

by 노력남자 2022. 9. 6.
반응형

이번 포스팅에선 Mockito를 이용해 스터빙한 메소드가 제대로 실행이 됐는지 확인해보는 메소드에 대해서 알아보겠습니다.

 

스터빙한 메소드를 검증하는 방법

 

verify 메소드를 이용해서 스터빙한 메소드가 실행됐는지, n번 실행됐는지, 실행이 초과되지 않았는지 등 다양하게 검증해볼 수 있습니다.

 

verify(T mock, VerificationMode mode)

 

위와 같은 형태로 쓰며 VerificationMode는 검증할 값을 정의하는 메소드입니다.

 

메소드명 설명 (테스트 내에서~)
times(n) 몇 번이 호출됐는지 검증
never 한 번도 호출되지 않았는지 검증
atLeastOne 최소 한 번은 호출됐는지 검증
atLeast(n) 최소 n 번이 호출됐는지 검증
atMostOnce 최대 한 번이 호출됐는지 검증
atMost(n) 최대 n 번이 호출됐는지 검증
calls(n) n번이 호출됐는지 검증 (InOrder랑 같이 사용해야 함)
only 해당 검증 메소드만 실행됐는지 검증
timeout(long mills) n ms 이상 걸리면 Fail 그리고 바로 검증 종료
after(long mills) n ms 이상 걸리는지 확인

timeout과 다르게 시간이 지나도 바로 검증 종료가 되지 않는다.
description 실패한 경우 나올 문구

 

예제

 

public class UserService {

    public User getUser() {
        return new User("effortguy", "1234");
    }
    
    public int getLoginErrNum() {
        return 1;
    }
    
    public void deleteUser() {}
}

 

목 객체만 만들고 별도로 스터빙하지 않은 이유는 어차피 스터빙 안 하면 null을 리턴하기 때문에 굳이 하지 않았습니다.

 

verify, VerificationMode 를 어떻게 사용했는지를 중점으로 봐주세요.

 

@ExtendWith(MockitoExtension.class)
public class VerifyMethod {

    @Mock
    UserService userService;

    @Test
    void testVerifyTimes() {
        userService.getUser();
        userService.getUser();

        verify(userService, times(2)).getUser();
    }

    @Test
    void testVerifyNever() {
        verify(userService, never()).getUser();
    }

    @Test
    void testAtLeastOne() {
        userService.getUser();

        verify(userService, atLeastOnce()).getUser();
    }

    @Test
    void testAtLeast() {
        //한 번만 실행하면 fail
        userService.getUser();
        userService.getUser();
        userService.getUser();

        verify(userService, atLeast(2)).getUser();
    }

    @Test
    void testAtMostOnce() {
        userService.getUser();
        // userService.getUser(); - 2번 이상 실행하면 fail

        verify(userService, atMostOnce()).getUser();
    }

    @Test
    void testAtMost() {
        userService.getUser();
        userService.getUser();
        userService.getUser();
        // userService.getUser(); - 6번 이상 실행하면 fail

        verify(userService, atMost(3)).getUser();
    }

    @Test
    void testOnly() {
        userService.getUser();
        // userService.getLoginErrNum(); - getUser()가 아닌 다른 메소드 실행 시 fail

        verify(userService, only()).getUser();
    }
}

 

결과

 

 

메소드 호출 순서 검증

 

메소드 호출 순서 검증을 위해 InOrder를 사용하면 됩니다. 사용 방법은 예제로 보겠습니다.

 

예제

 

InOrder를 inOrder("mock 객체명")으로 생성한 후 검증하고 싶은 순서에 맞게 verify를 써주면 됩니다.

 

InOrder을 테스트하면서 아까 위에서 테스트하지 않은 calls()와 아래 메소드를 같이 테스트하겠습니다.

 

verifyNoMoreInteractions(T mock) - 선언한 verify 후 해당 mock을 실행하면 fail

verifyNoInteractions(T mock) - 테스트 내에서 mock을 실행하면 fail

Interaction이란 mock 객체를 호출하는 걸 말합니다.

 

@ExtendWith(MockitoExtension.class)
public class VerifyInOrderMethod {

    @Mock
    UserService userService;

    @Mock
    ProductService productService;

    @Test
    void testInOrder() {

        // 이 순서로 하면 fail
        // userService.getLoginErrNum();
        // userService.getUser();
        userService.getUser();
        userService.getLoginErrNum();

        InOrder inOrder = inOrder(userService);

        inOrder.verify(userService).getUser();
        inOrder.verify(userService).getLoginErrNum();
    }

    @Test
    void testInOrderWithCalls() {

        // 이 순서로 하면 fail
        // userService.getUser();
        // userService.getLoginErrNum();
        // userService.getUser();

        userService.getUser();
        userService.getUser();
        userService.getLoginErrNum();

        InOrder inOrder = inOrder(userService);

        inOrder.verify(userService, calls(2)).getUser();
        inOrder.verify(userService).getLoginErrNum();
    }

    @Test
    void testInOrderWithVerifyNoMoreInteractions() {
        userService.getUser();
        // userService.getLoginErrNum(); - 실행하면 fail

        InOrder inOrder = inOrder(userService);

        inOrder.verify(userService).getUser();

        verifyNoMoreInteractions(userService); //위에 verify 이후 userService를 호출하면 fail
    }

    @Test
    void testInOrderWithVerifyNoInteractions() {
        userService.getUser();
        userService.getLoginErrNum();
        // productService.getProduct(); - 실행하면 fail
        
        InOrder inOrder = inOrder(userService);

        inOrder.verify(userService).getUser();
        inOrder.verify(userService).getLoginErrNum();

        verifyNoInteractions(productService); //productService를 호출하면 fail
    }
}

 

결과

 

 

다음 포스팅에선 Mockito를 BDD 스타일로 작성하는 법에 대해 알아보겠습니다.

 

읽어주셔서 감사합니다.

반응형

댓글