테스트 코드1 (JUnit과 Mockito)

오의석·2025년 1월 15일
0

샘플코드

@ExtendWith(MockitoExtension.class)
class RealImplTest {
    @Mock
    AService aService;
    @Mock
    BService bService;

    @InjectMocks
    private RealImpl realService;

	// 파일 생성 부분때문에 설정하였음
    @BeforeEach
    void beforeEach() {
        // Mock HttpServletRequest 및 HttpServletResponse 생성
        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();

        // RequestContextHolder에 설정
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request, response));
    }


    @Test
    void downloadMethod() {
        //given : 주어진 입력 값
        TestVo testVo = TestVo.builder().id("1").build();
        ResultVo vo = ResultVo.builder().id("2").build();
        CompletableFuture<List<ResultVo>> future = CompletableFuture.completedFuture(List.of(vo));

        doReturn(future)
                .when(aService)
                .selectList(any(ResultVo.class));
        doReturn("C:\\Users\\user\\Downloads\\Temp\\")
                .when(bService)
                .getTempPath();

        //when : 실제로 액션을 하는 테스트를 실행하는 과정
        realService.downloadMethod(testVo);

        //when then : 테스트를 검증하는 과정 (아래 코드는 에러가 나타나야 성공하는 코드)
        assertThrows(Exception.class, () -> realService.downloadMethod(new TestVo()));
    
    }

   
}

이 코드는 RealImpl 클래스의 downloadMethod 메소드를 테스트하는 단위 테스트 코드입니다. 테스트는 JUnit 5와 Mockito를 사용하여 작성되었습니다. 코드를 하나씩 설명하겠습니다.

1. 클래스 선언

@ExtendWith(MockitoExtension.class)
class RealImplTest {
  • @ExtendWith(MockitoExtension.class)은 JUnit 5에서 Mockito 확장을 사용하기 위해 설정하는 어노테이션입니다. 이 어노테이션을 통해 Mockito가 테스트 클래스에서 자동으로 Mock 객체를 생성하고 주입할 수 있습니다.

2. Mock 객체 선언

@Mock
AService aService;
@Mock
BService bService;
  • @Mock 어노테이션을 사용하여 AServiceBService 클래스의 Mock 객체를 생성합니다. 실제 객체가 아닌 가짜 객체가 생성되며, 이는 테스트에서 해당 서비스들이 어떻게 동작해야 하는지 설정할 수 있게 합니다.

3. RealImpl 객체 주입

@InjectMocks
private RealImpl realService;
  • @InjectMocksrealService 객체에 AServiceBService Mock 객체를 자동으로 주입하는 역할을 합니다. 이를 통해 RealImpl 클래스의 실제 메소드를 테스트할 수 있습니다.

4. beforeEach 메소드

@BeforeEach
void beforeEach() {
    MockHttpServletRequest request = new MockHttpServletRequest();
    MockHttpServletResponse response = new MockHttpServletResponse();
    
    RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request, response));
}
  • @BeforeEach는 각 테스트 메소드가 실행되기 전에 먼저 실행되는 메소드입니다.
  • 여기에서는 MockHttpServletRequestMockHttpServletResponse를 생성하고, RequestContextHolder에 이를 설정하여 HTTP 요청 및 응답에 대한 Mock 환경을 준비합니다. 이는 RealImpl 클래스의 메소드가 HTTP 요청/응답을 사용하는 경우에 필요한 설정입니다.

5. downloadMethod 테스트 메소드

@Test
void downloadMethod() {
    TestVo testVo = TestVo.builder().id("1").build();
    ResultVo vo = ResultVo.builder().id("2").build();
    CompletableFuture<List<ResultVo>> future = CompletableFuture.completedFuture(List.of(vo));

    doReturn(future)
            .when(aService)
            .selectList(any(ResultVo.class));
    doReturn("C:\\Users\\user\\Downloads\\Temp\\")
            .when(bService)
            .getTempPath();

    realService.downloadMethod(testVo);

    assertThrows(Exception.class, () -> realService.downloadMethod(new TestVo()));
}
  • @Test 어노테이션은 이 메소드가 JUnit 테스트 메소드임을 나타냅니다.

주어진 입력 값 (given)

TestVo testVo = TestVo.builder().id("1").build();
ResultVo vo = ResultVo.builder().id("2").build();
CompletableFuture<List<ResultVo>> future = CompletableFuture.completedFuture(List.of(vo));
  • TestVoResultVo 객체를 빌더 패턴을 사용하여 생성합니다.
  • CompletableFuture.completedFuture(List.of(vo))ResultVo 객체를 포함하는 완료된 CompletableFuture를 만듭니다. 이는 비동기 작업이 완료된 상태를 시뮬레이션합니다.

aServicebService의 Mock 동작 설정

doReturn(future)
        .when(aService)
        .selectList(any(ResultVo.class));
doReturn("C:\\Users\\user\\Downloads\\Temp\\")
        .when(bService)
        .getTempPath();
  • aService.selectList(any(ResultVo.class)) 호출 시 future 객체를 반환하도록 설정합니다.
  • bService.getTempPath() 호출 시 "C:\\Users\\user\\Downloads\\Temp\\" 경로를 반환하도록 설정합니다.

실제 테스트 실행

realService.downloadMethod(testVo);
  • realService.downloadMethod(testVo)를 호출하여 테스트를 실행합니다. 이 메소드는 RealImpl 클래스에 정의된 실제 downloadMethod 메소드를 실행합니다.

예외 처리 검증

assertThrows(Exception.class, () -> realService.downloadMethod(new TestVo()));
  • new TestVo()를 전달하여 downloadMethod를 다시 호출했을 때 예외가 발생하는지 확인합니다.
  • assertThrows는 예외가 발생할 것으로 예상되면 성공하고, 그렇지 않으면 실패하는 검증 방법입니다. 예외가 발생하면 테스트는 성공으로 간주됩니다.

6. 전체적인 테스트 흐름

  1. TestVoResultVo 객체를 준비하고, aService.selectList()bService.getTempPath()의 반환값을 설정합니다.
  2. downloadMethod를 호출하여 실제 메소드의 동작을 테스트합니다.
  3. TestVo 객체에 대해 downloadMethod가 예외를 던지는지 확인하여 예외 처리가 잘 되는지 검증합니다.

요약

이 코드는 RealImpl 클래스의 downloadMethodAServiceBService를 사용하여 정상적으로 동작하는지, 그리고 TestVo에 대해 예외가 발생하는지 확인하는 단위 테스트 코드입니다. Mockito를 사용하여 외부 의존성을 Mock 객체로 대체하고, 이를 통해 메소드의 동작을 검증합니다.

profile
끊임없이 나아가는 사람이 되어볼게요.

0개의 댓글