springboot-tdd
JUnit 5, Mockito, MockMvc, Testcontainers, JaCoCo를 사용한 Spring Boot 테스트 주도 개발. 기능 추가, 버그 수정, 리팩터링에 사용한다.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
JUnit 5, Mockito, MockMvc, Testcontainers, JaCoCo를 사용한 Spring Boot 테스트 주도 개발. 기능 추가, 버그 수정, 리팩터링에 사용한다.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
새 Spring Boot 서비스를 api-gateway + auth-api 에코시스템에 연결한다. auth-api 클라이언트 등록 → Gateway 라우팅 추가 → 서비스에 econo-passport 연동 → 동작 확인까지 한 번에 처리. 다음 상황에서 반드시 이 스킬을 사용한다: - "새 서비스 Gateway에 연결해줘", "새 서비스 auth 연동" - "서비스 등록해줘", "Gateway 뒤에 붙여줘" - "/register-service" 직접 호출 - 새 Spring Boot 서비스가 추가되고 인증이 필요할 때 ARGUMENTS: 서비스명, 서비스 경로(선택), 업스트림 URL(선택) 예: "EEOS-BE /Users/mando/study/eeos/EEOS-BE/eeos"
이 스킬은 사용자가 "PR 생성해줘", "PR 만들어줘", "pull request 생성", "pr 올려줘", "/git-pr" 등을 요청할 때 호출된다. 현재 브랜치의 커밋을 원격으로 push하고, `.github/PULL_REQUEST_TEMPLATE.md`를 채워 GitHub Pull Request를 생성한다.
신규 기능을 개발할 때 정책 문서 → 코드 → 테스트 순서로 작성한다. ADR은 기술적 결정에만 사용하고, 기능 정책은 docs/features/ 에 작성한다. 다음 상황에서 반드시 이 스킬을 사용한다: - "기능 추가해줘", "기획부터 해봐", "설계해봐" - 새로운 API 엔드포인트 또는 도메인 규칙이 생길 때 - "/new-feature" 직접 호출 ARGUMENTS: 기능 이름 또는 요구사항 (없으면 대화에서 추출)
Architecture Decision Record(ADR)를 작성한다. 기술적 결정사항, 설계 선택, 트레이드오프를 문서화하여 나중에 "왜 이렇게 했지?"를 알 수 있게 한다. 다음 상황에서 반드시 이 스킬을 사용한다: - "ADR 써줘", "결정사항 문서화해줘", "이 결정 기록해줘" - 기술 방향 선택 후 ("A 대신 B 쓰기로 했어") - 설계 논의가 끝났을 때 - 나중에 이 결정이 왜 내려졌는지 설명이 필요할 것 같을 때 - "/adr" 직접 호출 ARGUMENTS: 결정 내용 또는 결정 번호 (없으면 대화에서 추출)
AI 에이전트의 액션 스페이스, 도구 정의, 관측(Observation) 포맷을 설계·최적화해 작업 완수율을 높일 때 사용한다.
로컬 개발, 컨테이너 보안, 네트워킹, 볼륨 전략, 멀티 서비스 오케스트레이션을 위한 Docker 및 Docker Compose 패턴.
基于 SOC 职业分类
| name | springboot-tdd |
| description | JUnit 5, Mockito, MockMvc, Testcontainers, JaCoCo를 사용한 Spring Boot 테스트 주도 개발. 기능 추가, 버그 수정, 리팩터링에 사용한다. |
| origin | ECC |
80% 이상 커버리지(단위 + 통합)를 갖춘 Spring Boot 서비스를 위한 TDD 가이드.
@ExtendWith(MockitoExtension.class)
class MarketServiceTest {
@Mock MarketRepository repo;
@InjectMocks MarketService service;
@Nested
@DisplayName("마켓 생성 테스트")
class CreateTest {
@Test
@DisplayName("정상적인 마켓 생성")
void createValidMarket() {
// given
CreateMarketRequest req = new CreateMarketRequest("name", "desc", Instant.now(), List.of("cat"));
when(repo.save(any())).thenAnswer(inv -> inv.getArgument(0));
// when
Market result = service.create(req);
// then
assertThat(result.name()).isEqualTo("name");
verify(repo).save(any());
}
}
}
패턴:
@Nested + @DisplayName으로 테스트를 한글로 그룹화@DisplayName은 한글@ParameterizedTest를 사용한다@WebMvcTest(MarketController.class)
class MarketControllerTest {
@Autowired MockMvc mockMvc;
@MockBean MarketService marketService;
@Nested
@DisplayName("마켓 목록 조회 테스트")
class ListTest {
@Test
@DisplayName("마켓 목록 정상 조회")
void listMarkets() throws Exception {
// given
when(marketService.list(any())).thenReturn(Page.empty());
// when & then
mockMvc.perform(get("/api/markets"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.content").isArray());
}
}
}
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
class MarketIntegrationTest {
@Autowired MockMvc mockMvc;
@Nested
@DisplayName("마켓 생성 통합 테스트")
class CreateIntegrationTest {
@Test
@DisplayName("정상적인 마켓 생성 요청 시 201 응답")
void createMarket() throws Exception {
// given
String requestBody = """
{"name":"Test","description":"Desc","endDate":"2030-01-01T00:00:00Z","categories":["general"]}
""";
// when & then
mockMvc.perform(post("/api/markets")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andExpect(status().isCreated());
}
}
}
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Import(TestContainersConfig.class)
class MarketRepositoryTest {
@Autowired MarketRepository repo;
@Nested
@DisplayName("마켓 저장 및 조회 테스트")
class SaveAndFindTest {
@Test
@DisplayName("저장 후 이름으로 조회")
void saveAndFindByName() {
// given
MarketEntity entity = new MarketEntity();
entity.setName("Test");
// when
repo.save(entity);
Optional<MarketEntity> found = repo.findByName("Test");
// then
assertThat(found).isPresent();
}
}
}
@DynamicPropertySource로 JDBC URL을 Spring 컨텍스트에 주입한다Maven 예시:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.14</version>
<executions>
<execution>
<goals><goal>prepare-agent</goal></goals>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals><goal>report</goal></goals>
</execution>
</executions>
</plugin>
assertThat)를 선호한다jsonPath를 사용한다assertThatThrownBy(...)를 사용한다class MarketBuilder {
private String name = "Test";
MarketBuilder withName(String name) { this.name = name; return this; }
Market build() { return new Market(null, name, MarketStatus.ACTIVE); }
}
mvn -T 4 test 또는 mvn verify./gradlew test jacocoTestReport기억할 점: 테스트는 빠르고, 격리되어 있으며, 결정적이어야 한다. 구현 세부가 아닌 동작을 테스트한다.