skill/Java.Kotlin

Jacoco url 기준 테스트

have a nice day :D 2025. 9. 16. 08:24
반응형


“웹 서비스 기준, URL 기준 Jacoco test 처리” → 쉽게 말해 컨트롤러(API URL 단위로 테스트를 작성하고, 그 결과를 Jacoco 커버리지에 반영하는 방법**을 말씀하시는 거죠.


---

1. 기본 개념

Jacoco는 테스트 실행 시 코드(클래스/메서드/라인)가 실제로 호출되었는지만 체크합니다.

따라서 “URL 기준 테스트” = 컨트롤러 URL 호출 테스트(MockMvc/WebTestClient) 를 작성하면 → 해당 URL을 처리하는 컨트롤러/서비스 코드 라인이 커버리지에 잡히는 구조입니다.

즉, URL 단위의 API 테스트 = Jacoco 기준 커버리지 확보.



---

2. Spring Boot (Kotlin) URL 테스트 예시

컨트롤러

@RestController
@RequestMapping("/api/users")
class UserController(
    private val service: UserService
) {
    @GetMapping("/{id}")
    fun getUser(@PathVariable id: Long): ResponseEntity<UserDto> {
        val user = service.getUser(id)
        return ResponseEntity.ok(UserDto.from(user))
    }
}

테스트 (MockMvc 기반)

@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest(
    @Autowired val mockMvc: MockMvc
) {
    @Test
    fun `GET 사용자 조회 API`() {
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk)
            .andExpect(content().contentType("application/json"))
    }
}

👉 여기서 mockMvc.perform(get("/api/users/1")) 호출이 발생하면:

컨트롤러(UserController.getUser) 메서드 실행

그 안에서 호출된 서비스(UserService.getUser) 도 실행

결과적으로 해당 코드 라인들이 Jacoco 리포트에 **녹색(실행됨)**으로 반영됩니다.



---

3. Jacoco 설정 (Gradle)

plugins { jacoco }

tasks.test {
    useJUnitPlatform()
}

tasks.jacocoTestReport {
    dependsOn(tasks.test)
    reports {
        xml.required.set(true)   // Jenkins용
        html.required.set(true)  // 로컬 확인용
    }
}

실행:

./gradlew test jacocoTestReport

리포트 확인:

build/reports/jacoco/test/html/index.html



---

4. 결과

URL 단위로 테스트 작성 → Jacoco는 해당 URL을 처리하는 컨트롤러/서비스 코드의 실행 여부를 자동 집계

여러 URL을 테스트할수록 커버리지 ↑

QA/감리 입장에서는 “Swagger API URL = 테스트 케이스” / “Jacoco = 실행 증적” 으로 엮을 수 있습니다.



---

5. 권장 흐름

1. Swagger/OpenAPI 기준으로 API 목록 정리


2. 각 URL마다 MockMvc/WebTestClient 테스트 작성


3. Jenkins에서 ./gradlew test jacocoTestReport 실행


4. Jacoco 리포트와 Swagger 매핑표(엑셀) 같이 제출




---

✅ 정리

웹 서비스(URL 기준 테스트) = MockMvc/WebTestClient로 엔드포인트 호출

Jacoco는 그 실행 결과를 코드 라인 단위로 자동 집계

따라서 “URL 기준 단위테스트 산출물”은 Swagger 기반 API 테스트 목록 + Jacoco 리포트로 완성할 수 있습니다.



---

좋은 질문이에요 👍 단위테스트/통합테스트 얘기하다 보면 Mocking과 Stub이라는 용어가 자주 나오죠.
두 개는 비슷해 보이지만 미묘한 차이가 있어요.


---

🔎 기본 개념

1. Stub (스텁)

미리 정해둔 응답만 돌려주는 가짜 객체

아주 단순한 대체품 → “이 메서드를 호출하면 무조건 같은 결과를 준다”

조건이나 동작을 복잡하게 제어하지 않고, 딱 고정된 값을 반환


👉 비유: “전화기 더미(dummy)”처럼 응답은 오지만, 똑같은 녹음 메시지만 들려주는 전화기

예:

class UserRepositoryStub : UserRepository {
    override fun findById(id: Long): User? {
        return User(id, "Kim")  // 항상 같은 값 반환
    }
}


---

2. Mock (목)

행동을 시뮬레이션하고, 호출 여부/횟수까지 검증할 수 있는 객체

Stub의 기능(값 반환) + “이 메서드가 몇 번 호출됐나, 어떤 파라미터로 불렸나”까지 체크 가능

보통 Mock 프레임워크(MockK, Mockito)를 사용해 생성


👉 비유: “연습 상대 배우(actor)”처럼 대본에 따라 대답도 하고, 네가 나한테 몇 번 질문했는지도 다 기록하는 상대역

예:

val repo = mockk<UserRepository>()
every { repo.findById(1L) } returns User(1L, "Kim")

val service = UserService(repo)
val user = service.getUser(1L)

// 호출 검증
verify(exactly = 1) { repo.findById(1L) }


---

🔎 차이 정리

구분 Stub Mock

목적 테스트용 값/상황 제공 값 제공 + 행동 검증
동작 단순히 미리 정해둔 값 반환 호출 횟수, 파라미터, 순서까지 검증
구현 직접 가짜 클래스 작성 Mock 프레임워크로 자동 생성
사용처 외부 시스템 단순 대체, 빠른 응답 협력 객체와의 상호작용 검증



---

🔎 예시 (같은 상황, 다른 접근)

// Stub
class PaymentStub : PaymentGateway {
    override fun pay(amount: Int) = true // 무조건 성공
}
val service = OrderService(PaymentStub())
val result = service.order(1000)
assert(result == true) // 값만 검증

// Mock
val payment = mockk<PaymentGateway>()
every { payment.pay(1000) } returns true
val service = OrderService(payment)
service.order(1000)
verify(exactly = 1) { payment.pay(1000) } // 호출 검증까지


---

✅ 정리

Stub = 값만 고정해서 주는 가짜 (단순, 하드코딩)

Mock = Stub 기능 + 호출 검증까지 가능한 강력한 가짜

요즘은 Mock 프레임워크(MockK, Mockito) 를 주로 쓰고, Stub은 필요할 때 간단 구현으로 사용



---




반응형

'skill > Java.Kotlin' 카테고리의 다른 글

path value에 /가 들어갈때  (0) 2025.11.05
데이터 클래스를 쿼리스트링 변환  (0) 2025.10.28
Jacoco 리포트 화면  (0) 2025.09.16
jacoco 개념 + 외부 연동 MockkBean 처리  (0) 2025.09.15
where in 조건 갯수 제한  (2) 2025.07.30