업무 기록/ETC

테스트 코드 작성 이유 및 방법 - SpringBoot, Kotlin

code2772 2024. 8. 9. 13:24
728x90
반응형

 

<내가 생각하는 테스트 코드 작성 이유>

 

테스트 코드의 장점은 다양하다 그 중 내가 생각하는 가장 큰 이유는 여러명이 프로젝트를 작업하는 경우에 있다. 각자의 코드를 변경한 경우 연관된 코드로 문제가 발생할 수 있다. 문제를 방지하기 위해 코드 변경 시마다 테스트를 일일히 하기에는 문제가 있어 테스트 코드를 작성하여 변경 시마다 자동으로 테스트가 실행되도록 설정하고 안정성과 효율성을 크게 향상시킬 수 있는 측면이다.

 

 


<사전지식/내용>

 

@Mock:

Mockito를 사용하여 가짜 객체(mock)를 생성합니다. 여기서는 rcsBrandRepository의 가짜 객체를 생성하여 실제 데이터베이스 연결 없이 테스트할 수 있게 합니다. 

 


@InjectMocks: 

가짜 객체를 자동으로 주입합니다. 여기서는 rcsBrandServiceImpl에 mock 객체들을 주입합니다.

 


@BeforeEach:

 각 테스트 메서드 실행 전에 실행될 설정을 정의합니다. 여기서는 MockitoAnnotations.openMocks(this)를 호출하여 각 테스트마다 새로운 상태의 mock 객체들을 사용할 수 있게 합니다.

 

 

 <테스트 토드 작성 방식>

 

Given (주어진 상황):
테스트를 위한 초기 조건이나 상태를 설정합니다.
테스트에 필요한 객체들을 준비하고 초기화합니다.


When (실행):
테스트하고자 하는 실제 동작이나 기능을 실행합니다.
주로 테스트 대상 메서드를 호출하는 부분입니다.


Then (결과 확인):
실행 결과를 검증합니다.
예상한 결과와 실제 결과를 비교하여 테스트의 성공 여부를 판단합니다.

 


<테스트 코드 예시>

class RcsBrandServiceImplTest {

    @Mock
    // Mock 어노테이션은 Mockito 사용하여 가짜 객체(mock)을 생성
    // rcsBrandRepository 의 가짜 객체 생성하여  실제 DB 연결 없이 테스트 가능
    private lateinit var rcsBrandRepository: RcsBrandRepository

    @InjectMocks
    // InjectMocks 은 가짜 객체 자동 주입한다.
    private lateinit var rcsBrandServiceImpl: RcsBrandServiceImpl

    @BeforeEach
    // BeforeEach 각 테스트 메서드 실행 전 실행될 설정 정의 기능
    fun setup(){
        MockitoAnnotations.openMocks(this)
        // MockitoAnnotations.openMocks(this) 각 테스트마다 새로운 상태의 mock 객체들을 사용할 수 있다.
    }

    @Test
    @DisplayName("브랜드 값 전체 조회 내림차순")
    fun `test getAllRcsBrands`(){

        // Given : 테스트 필요한 초기 조건 설정
        val pageable = PageRequest.of(0,10)

        val now = LocalDateTime.now()
        val mockBrands = listOf(
            RcsBrand(1, "brand1", "key1", "Brand1", "user1", now, now, now,"ACTIVE"),
            RcsBrand(2, "brand2", "key2", "Brand2", "user2", now, now, now,"ACTIVE")
        )
        val mockPage: Page<RcsBrand> = PageImpl(mockBrands)

        // when : 해당 JPA 호출 시 mockPage 반환
        `when`(rcsBrandRepository.findAllByOrderByRegisterDateDesc(pageable)).thenReturn(mockPage)
        val result = rcsBrandServiceImpl.getAllRcsBrands(pageable)

        // then : 테스트 결과 검증 -> 반환된 결과가 예상한 mockpage와 일치하는지 확인
        assertEquals(mockPage, result)
        verify(rcsBrandRepository).findAllByOrderByRegisterDateDesc(pageable)

    }

 

 

위 테스트는 getAllRcsBrands 메서드를 검증합니다:

  • Given: 테스트에 필요한 초기 조건을 설정합니다.
  • When: 실제 테스트할 동작을 수행합니다. 여기서는 rcsBrandRepository.findAllByOrderByRegisterDateDesc가 호출될 때 mockPage를 반환하도록 설정하고, 실제 메서드를 호출합니다.
  • Then: 테스트 결과를 검증합니다. 반환된 결과가 예상한 mockPage와 일치하는지 확인하고, 메서드가 실제로 호출되었는지 verify합니다.

 

 

이 후 테스트를 실행하면 하단과 같이 결과를 확인할 수 있다.

 

반응형