“웹 서비스 기준, 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 |