一键导入
write-test-code
프로젝트 테스트 작성 시 어노테이션 선택, Fixture 활용, FCM 주의사항 안내. "테스트 작성해줘", "단위 테스트", "통합 테스트", "@WebMvcTest", "Mock 테스트" 요청 시 반드시 참고.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
프로젝트 테스트 작성 시 어노테이션 선택, Fixture 활용, FCM 주의사항 안내. "테스트 작성해줘", "단위 테스트", "통합 테스트", "@WebMvcTest", "Mock 테스트" 요청 시 반드시 참고.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
이 저장소에서 신규 기능 개발, 기존 기능 리팩토링, 버그 수정, API 변경, 도메인 정책 변경을 수행할 때 설계 문서화, Red-Green-Refactor 테스트 작성, 구현, 관련 테스트와 전체 테스트 검증, 배포/PR 확인까지 자연스럽게 이어가도록 사용하는 워크플로우 스킬이다.
이 저장소에서 브랜치 변경 내역을 바탕으로 프로젝트 PR 본문 형식에 맞춰 요약, 상세 작업 내용, 참고사항을 작성할 때 사용한다.
이 저장소에서 변경 내용을 바탕으로 프로젝트 커밋 메시지 규칙에 맞는 커밋 메시지를 만들거나, staged 변경을 확인해 적절한 Type과 제목을 정리할 때 사용한다.
이 저장소에서 큰 기능 설계나 정책 변경을 시작하기 전에 AGENTS.md, CONTEXT.md, docs/adr, docs/history, 실제 코드를 근거로 요구사항을 질문하고 도메인 용어와 아키텍처 결정 및 작업 이력을 문서화할 때 사용한다.
이 저장소에서 신규 기능 개발, 기능 수정, PRD 작성, API 변경, 스케줄러/Redis/FCM/외부 API 연동 작업을 할 때 latency, availability, error rate 관점의 SLO 영향을 점검하고 필요한 metric, 테스트, 운영 확인 항목을 정리할 때 사용한다.
이 저장소에서 기능 요청, 정책 변경, API 변경, 앱 요구사항을 docs/history/{0001}-{기능명-slug}/PLAN.md 형식의 PRD 또는 구현 계획으로 정리할 때 사용한다.
| name | write-test-code |
| description | 프로젝트 테스트 작성 시 어노테이션 선택, Fixture 활용, FCM 주의사항 안내. "테스트 작성해줘", "단위 테스트", "통합 테스트", "@WebMvcTest", "Mock 테스트" 요청 시 반드시 참고. |
| 목적 | 어노테이션 |
|---|---|
| 컨트롤러 요청/검증 | @WebMvcTest + @AutoConfigureMockMvc(addFilters = false) |
| 서비스 비즈니스 로직 | @ExtendWith(MockitoExtension.class) |
| Repository / JPQL | @PersistenceTest (MySQL Testcontainer) |
| 전체 플로우 | @IntegrationTest (MySQL + Redis Testcontainer) |
| Redis 슬라이스 | @DataRedisTest + RedisContainerInitializer |
excludeFilters = @Filter(type = ASSIGNABLE_TYPE,
classes = {SecurityConfig.class, JwtAuthenticationFilter.class})
// 협력 빈: @MockitoBean
// SecurityContext 수동 설정 후 @AfterEach에서 clearContext()
| 테스트 종류 | 메서드 |
|---|---|
| 서비스 단위 테스트 | MemberFixture.MEMBER_1.toMockEntity() (id 포함) |
| Persistence / Integration | memberRepository.save(MemberFixture.MEMBER_1.toEntity()) |
파일 위치: src/test/java/akuma/whiplash/common/fixture/
MemberFixture MEMBER_1~20AlarmFixture ALARM_01~20AlarmOccurrenceFixturebuildOccurrence(), buildAlarm() 같은 엔티티 생성 헬퍼를 만들지 않는다.toMockEntity() / toEntity()를 사용한다.toEntity(...) 오버로드나 전용 메서드를 추가한다.AlarmEntity alarm = AlarmFixture.ALARM_01.toMockEntity();
AlarmEntity savedAlarm = alarmRepository.save(AlarmFixture.ALARM_01.toEntity(member));
AlarmOccurrenceEntity occurrence =
AlarmOccurrenceFixture.ALARM_OCCURRENCE_01.toEntity(savedAlarm);
local 프로파일 → MockFcmService(@Primary) 자동 등록, FCM 실제 호출 없음
INVALID_ prefix 토큰 → 실패 처리
status, isSuccess, code 중심으로 검증한다.message)는 사용자 노출 문구라 변경 가능성이 높으므로 String literal로 직접 검증하지 않는다.getMessage()를 사용한다.getCustomCode()를 우선 사용한다.ApplicationException을 검증할 때는 hasMessage(...)보다 getCode()로 ErrorCode enum을 비교한다.// ✅ 권장
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.isSuccess").value(false))
.andExpect(jsonPath("$.code").value(ALARM_DELETE_REQUIRES_PAYMENT.getCustomCode()));
// ✅ 서비스 단위 테스트 권장
assertThatThrownBy(() -> alarmCommandService.removeAlarmByAd(memberId, alarmId, request))
.isInstanceOfSatisfying(ApplicationException.class, e ->
assertThat(e.getCode()).isEqualTo(ALARM_DELETE_REQUIRES_PAYMENT)
);
// ⚠️ 메시지까지 계약으로 보장해야 하는 경우에만 사용
.andExpect(jsonPath("$.message").value(ALARM_DELETE_REQUIRES_PAYMENT.getMessage()));
// ❌ 지양: 문구 변경만으로 테스트가 깨짐
.andExpect(jsonPath("$.message").value("결제 삭제가 필요한 알람입니다."));
@Nested inner class가 메서드마다 있는가?success() / fail_{이유}() 네이밍인가?@DisplayName 문장형, "~테스트" 없는가?// given / // when / // then 있는가?toMockEntity(), Persistence→toEntity() 구분했는가?hasMessage(...) 대신 ApplicationException#getCode()를 검증했는가?