카테고리 없음

mockito를 이용해서 외부 API mocking 테스트

Lahezy 2023. 6. 7.
728x90

시작

팀프로젝트를 내에서 기업의 사업자 번호를 확인하는 로직이 필요했는데 해당 로직을 팀원분께서 공공기관 API를 활용하여 해결할 수 있도록 코드를 작성해 주셨다. 하지만 회원 가입 로직을 작성하고 테스트하려 하는 과정에서 어떻게 테스트를 해야 하나에 대한 고민이 수중위로 올라왔다.

 

실제 서비스에서 단순히 한번 사용자를 만드는거라면 테스트 데이터를 만들어서 사용하면 되지만

기업회원이 회원가입을 하는 로직내에 포함되어 있는 사업자 인증 로직을 테스트 동작시마다 계속해서 API 요청을 하는 것은 무리라고 생각했다. 

 

이 과정에서 과거 다른 개발자 분들이 말하시던 모킹을 해볼까 하는 생각이 들었다.

사실 현재 프젝에서는 컨트롤러 테스트 시에 mock mvc를 이용해서 테스트 하고 있어

mockito사용은 처음이였다. 

 

mockito 사용법(mockito usage) :: JDM's Blog

Spring Boot - Mockito를 이용해 외부라이브러리를 이용하는 서비스 테스트하기

 

위와 같은 블로그를 참고하여 해당 로직을 모킹 해보았다. 

 

도전

@MockBean
private CompanyRegistrationValidator companyRegistrationValidator;

private UserRequestDto userRequestDto;

@BeforeEach
void init() {
    userRequestDto = new UserRequestDto("nickname", "name", "password", "email@naver.com", "010-7558-2452", "USER");
    //벨리데이터 모킹
    when(companyRegistrationValidator.validateCompanyRegistration(any())).thenReturn(true);
    // 다음과 같이 모킹하여 사용한다.
    // 해당 로직을 호출하면 true를 리턴해준다.
}
@Test
@DisplayName("기업회원 회원가입을 확인한다. ")
public void signupCompany() {
    //given
    UserRequestDto companyRequestDto = new UserRequestDto("Bnickname", "Bname", "Bpassword", "Bemail@naver.com", "010-7558-2452", "BUSINESS");
    CompanyRegistrationDto companyRegistrationDto = new CompanyRegistrationDto("12345678", "20230526", "test", "test", "(주)테스트", "0000000000000", "부동산업", "부동산중개업", "test", "test");

    // when
    userService.signUpCompany(new CompanyRequestDto(companyRequestDto, companyRegistrationDto));

    //then
    User savedUser = userService.findUserByEmail(companyRequestDto.getEmail());
    assertThat(savedUser.getEmail()).isEqualTo(companyRequestDto.getEmail());
}

singUpCompany로직내에서 동작하는 validateCompanyRegistration로직을 true로 리턴하게 만들어

테스트 사업자 번호를 임의로 만들어 넣어도 동작할 수 있도록 테스트하였다.

 

결과

결과는 성공

 

모킹을 해보면서 이렇게 편리할 수가..라고 생각했다

생각을 하면서 머릿속에 추상적이었던 Mock과 Mockito를 알아보기로 했다.

 

Mock과 Mockito

Mock이란?

실제 객체와 비슷하게 동작하지만 프로그래머가 행동을 관리하는 객체로 테스트 중에 다른 객체를 대신하여 동작하도록 만들어진 가짜 객체이다.

 

Mockito란?

Mock객체의 생성을 쉽게 하고 검증할 수 있는 방법을 제공하는 프레임 워크로 리플렉션, 다이내믹 프락시를 활용하여 가짜 객체를 만들거나, stubbing, 검증 기능을 제공한다.

 

Mock를 사용해서 테스트를 하는 이유는 위의  코드 상황처럼 애플리케이션이 외부 API를 사용하거나 외부 라이브러리를 사용하는 경우 모든 상황을 고려하여 테스트 케이스를 짜는 것이 아닌 해당 로직이 어떻게 작동할지 예측하여 mock객체를 만들어서 편리하게 테스트를 할 수 있기 때문이다.

 

mockito를 활용하여 mock을 제어할 수 있는 행위로는 다음과 같은 것이 있다고 한다.

1. mock 객체 생성(모의객체 생성)

2. stubbing (가짜 반환값 설정)

3. 테스트 실행

4. 검증
.. 다양하다..

 

build.gradle , mockito 의존성 추가

//mockito(build. gradle에 추가)
testImplementation 'org.mockito:mockito-core'

 

간단한 Mockito 사용 예시 코드

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

// 테스트 클래스
public class MockTest {
    // 테스트 대상 클래스
    private class MyClass {
        public String getValue() {
            return "real value";
        }
    }

    @Test
    @DisplayName("stubbing 예시")
    public void test1() {
        // Mock 객체 생성
        MyClass mockObject = mock(MyClass.class);

        // Stubbing: 메서드 호출 시 반환값 설정
        when(mockObject.getValue()).thenReturn("mocked value");

        // 테스트 대상 메서드 실행
        String result = mockObject.getValue();

        // 검증: 예상된 값과 일치하는지 확인
        assertThat(result).isEqualTo("mocked value");

        // 검증: 메서드 호출 횟수 검증
        verify(mockObject, times(1)).getValue();

        assertThat(mockObject.getValue()).isEqualTo("mocked value");
        verify(mockObject, times(2)).getValue();
    }
}

 

 

참고

모키토 프레임워크(Mockito framework)

Mockito란? Mockito 사용하기

mockito 사용법(mockito usage) :: JDM's Blog

Spring Boot - Mockito를 이용해 외부라이브러리를 이용하는 서비스 테스트하기

https://www.baeldung.com/java-spring-mockito-mock-mockbean

 

728x90

댓글