Skip to content
Back to skills

Introduce Assertion

ASecurity

암묵적 가정(null 아님·범위·상태)을 Assert/Validate로 명시하여 가정 위반 시 즉시 발견. "assertion 추가", "전제 조건 명시", "가정을 코드로", "/introduce-assertion" 요청 시 사용. 단, 반복되는 null 검사를 객체로 대체하는 것은 /introduce-special-case가 적합. /introduce-assertion [commit-ref]로 호출.

  • 8 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 20, 2026
code-qualitygojavabashspringrefactoringgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 20, 2026

npx -y skills add msbaek/msbaek-claude-plugins --skill introduce-assertion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Introduce Assertion?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Introduce Assertion
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/msbaek-introduce-assertion/badge)](https://www.skillsdirectory.com/skills/msbaek-introduce-assertion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: introduce-assertion
description: 암묵적 가정(null 아님·범위·상태)을 Assert/Validate로 명시하여 가정 위반 시 즉시 발견. "assertion 추가", "전제 조건 명시", "가정을 코드로", "/introduce-assertion" 요청 시 사용. 단, 반복되는 null 검사를 객체로 대체하는 것은 /introduce-special-case가 적합. /introduce-assertion [commit-ref]로 호출.
argument-hint: "[commit-ref]"
---

# Introduce Assertion

## GOAL

코드가 암묵적으로 가정하는 조건을 assertion으로 명시하여:
- 가정 위반 시 즉시 발견 (원인과 증상의 거리 단축)
- 주석보다 강력한 실행 가능한 문서
- 계약 기반 프로그래밍의 경량 버전

## CONSTRAINTS

- **계열**: Tidy — 후보 보고 후 **승인 없이 적용** (`../../references/refactoring-procedure.md` §0·§3-A)
- **동작 변경 금지**: assertion 추가만 수행 (기존 로직 변경 없음)
- **테스트 수정 금지**: assertion 추가가 테스트를 실패시키면 되돌리기
- **명시적 git add**: `git add -A` 금지, 변경된 파일만 명시

### Assertion 도구 선택 (프로젝트 의존성 자동 감지)

프로젝트의 빌드 파일(build.gradle 또는 pom.xml)을 확인하여 자동 선택:

1. **Spring 의존성 있음** → `org.springframework.util.Assert`
2. **Apache Commons 있음** → `org.apache.commons.lang3.Validate`
3. **둘 다 없음** → `java.util.Objects.requireNonNull` + `IllegalArgumentException`

> Java `assert` 키워드는 `-ea` 플래그가 필요하여 프로덕션에서 비활성화될 수 있으므로 사용하지 않음

## 적용 패턴

### Before: 암묵적 가정 (Spring Assert)
```java
public double calculateDiscount(double price, double rate) {
    // price는 양수, rate는 0~1 사이여야 함 (주석 또는 아무것도 없음)
    return price * rate;
}
```

### After: assertion으로 가정 명시
```java
import org.springframework.util.Assert;

public double calculateDiscount(double price, double rate) {
    Assert.isTrue(price > 0, "price must be positive: " + price);
    Assert.isTrue(rate >= 0 && rate <= 1, "rate must be between 0 and 1: " + rate);
    return price * rate;
}
```

### 추가 예시: Apache Commons Validate
```java
import org.apache.commons.lang3.Validate;

public String formatName(Customer customer) {
    Validate.notNull(customer, "customer must not be null");
    Validate.notBlank(customer.getFirstName(), "firstName must not be blank");
    return customer.getFirstName() + " " + customer.getLastName();
}
```

### 추가 예시: 사후 조건 (결과 검증)
```java
public int allocateSlots(int requested, int available) {
    int allocated = Math.min(requested, available);
    Assert.isTrue(allocated >= 0, "allocated slots must not be negative: " + allocated);
    Assert.isTrue(allocated <= available, "allocated exceeds available: " + allocated + " > " + available);
    return allocated;
}
```

## 적용 기준

### 적용 대상
- 메서드가 특정 조건을 가정하지만 명시하지 않은 경우
- 내부 메서드(private/package-private)의 전제 조건
- 계산 결과의 사후 조건 (결과값 범위 검증)
- 알고리즘의 불변식 (invariant)
- null이 아닌 것을 암묵적으로 가정하는 경우

### 적용 제외
- **public API의 입력 검증**: assertion이 아니라 명시적 예외(IllegalArgumentException 등)를 사용해야 함
- **비즈니스 규칙 검증**: 도메인 로직으로 처리해야 할 것
- **이미 Guard Clause나 예외로 처리된 조건**: 중복
- **외부 입력(사용자, API 응답)**: 시스템 경계는 명시적 검증 필요

### 주의사항
- assertion 실패 = 프로그래머의 버그 (예상치 못한 상황)
- 예외(Exception) = 예상 가능한 오류 상황 (사용자 입력 오류 등)
- 이 구분이 모호하면 사용자에게 질문

## OUTPUT FORMAT

### 실행 절차

공통 골격(대상 파일 수집 → 후보 제시(계열별 승인 규칙) → 적용 → 테스트 → 커밋/되돌리기, 브랜치·PR이
필요한 조건)은 이 스킬 디렉터리 기준 `../../references/refactoring-procedure.md`가 정본이다.
아래는 이 기법에 고유한 부분만 규정한다.

#### 사전 확인: 프로젝트 의존성 (공통 절차 1단계 앞)

```bash
# Gradle 프로젝트
grep -l "spring" build.gradle 2>/dev/null || grep -l "commons-lang3" build.gradle 2>/dev/null

# Maven 프로젝트
grep -l "spring" pom.xml 2>/dev/null || grep -l "commons-lang3" pom.xml 2>/dev/null
```
결과에 따라 assertion 도구를 선택하고 사용자에게 안내:
```
프로젝트에서 Spring 의존성이 감지되었습니다.
org.springframework.util.Assert를 사용합니다.
```

#### 후보 식별 (공통 절차 2단계)

- 암묵적 가정 패턴 탐지:
  - null 참조 없이 메서드 호출하는 경우
  - 범위 가정 (양수, 0~1, 비어있지 않음 등)
  - 상태 가정 (초기화 완료, 특정 상태 등)
- 각 후보에 대해:
  - 파일명 및 라인 번호
  - 가정 내용 설명
  - 추가할 assertion 코드

#### 후보 제시 예시 (공통 절차 3단계)

```
발견된 후보 3개 (Spring Assert 사용):

1. PricingService.java:20
   가정: price > 0, rate는 0~1
   → Assert.isTrue(price > 0, ...)
   → Assert.isTrue(rate >= 0 && rate <= 1, ...)

2. OrderProcessor.java:45
   가정: order != null, order.getItems() 비어있지 않음
   → Assert.notNull(order, ...)
   → Assert.notEmpty(order.getItems(), ...)

→ 승인 없이 적용 (Tidy 계열)
```

#### 리팩토링 적용 (공통 절차 4단계)

- import 문 추가
- 메서드 시작 부분에 assertion 추가
- (사후 조건인 경우) return 직전에 assertion 추가

커밋 메시지: `refactor: introduce assertions in <클래스명>` (공통 절차 6단계)

### 출력 예시
```
완료: Introduce Assertion (Spring Assert)

변경 내용:
- PricingService.java:20
  전제 조건: Assert.isTrue(price > 0), Assert.isTrue(rate >= 0 && rate <= 1)

- OrderProcessor.java:45
  전제 조건: Assert.notNull(order), Assert.notEmpty(order.getItems())

테스트: 모든 테스트 통과 (23 tests)
커밋: refactor: introduce assertions in PricingService, OrderProcessor
```

## FAILURE CONDITIONS

공통 실패 조건(계열별 승인 규칙 위반, 테스트 실패 방치, 테스트 수정, 커밋 단위, `git add -A`, heredoc
한글 메시지)은 `../../references/refactoring-procedure.md`에 있다. 아래는 이 기법에 고유한 것만.

- [ ] 테스트가 실패함 (assertion 추가 후)
- [ ] public API의 입력 검증에 assertion을 사용함 (예외를 써야 함)
- [ ] Java `assert` 키워드를 사용함 (프로덕션 비활성화 위험)
- [ ] 이미 Guard Clause로 보호된 조건에 중복 assertion 추가

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…