- doSetValue()의 TYPE_BIGDECIMAL case에 isValid() 검사 추가 - 자릿수 초과 오류 발생 시점이 getData()에서 setData()로 통일 - 테스트: 자릿수 초과 3건 기대 예외를 InvalidDataTypeException → MessageSetDataException으로 변경 - JSON_VALIDATION_TEST_PLAN.md 내용 최신화 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.2 KiB
JSONMessage Validation 단위테스트 작업 내역
브랜치
feature/json-validation-test
커밋
ae629d5 — JSONMessage validation 단위테스트 추가 및 SystemKeys 버그 수정
(최신) — doSetValue() 자릿수 검사 setData() 시점으로 이동 및 테스트 수정
1. 목표
JSONMessage의 두 가지 validation 오류 시나리오를 단위테스트로 검증한다.
| 시나리오 | 발생 시점 | 결과 |
|---|---|---|
| 숫자형 필드에 타입 불일치 문자열 입력 | setData() |
✅ 정상 동작 확인 |
| 숫자형 필드의 자릿수 초과 | setData() |
✅ doSetValue() 개선으로 setData() 시점으로 통일 |
2. 수정 파일
2-1. SystemKeys.java — 버그 수정
isValidationEnabled()가 validationEnabled 필드를 무시하고 false를 하드코딩으로 반환하는 버그.
reload()는 transformer.validation 시스템 프로퍼티를 읽어 필드에 저장하지만 반환값에 반영되지 않았다.
// 수정 전
public static boolean isValidationEnabled() { return false; }
// 수정 후
public static boolean isValidationEnabled() { return validationEnabled; }
2-2. init_json_validation.sql — 신규
JSONMessageValidationTest 전용 테스트 데이터. 공유 init 파일(init_tseaitr07/08.sql)을 수정하지 않기 위해 별도 파일로 분리.
tseaitr07:EAI_UJSONTYPE_REQ1레이아웃 헤더 (타입: JSON)tseaitr08: 레이아웃 아이템 5건
| 필드명 | 타입코드 | length | decimal | 정수부 최대 |
|---|---|---|---|---|
| INT_VALUE | 2102 (INT) | 5 | 0 | — |
| LONG_VALUE | 2103 (LONG) | 10 | 0 | — |
| BIG_VALUE | 2118 (BIGDECIMAL) | 10 | 5 | 4자리 |
| BIG15_VALUE | 2118 (BIGDECIMAL) | 15 | 0 | 15자리 |
정수부 최대 =
length - decimal - 1
2-3. JSONMessageValidationTest.java — 신규
@DataJpaTest + H2 인메모리 DB 기반 JUnit 5 테스트. 테스트 7개 전체 통과.
기존 방식(AllTests.setParams() + TransformEngine.getInstance())은 Spring 컨텍스트 없이 실행 시 NPE가 발생했다. @DataJpaTest + @ContextConfiguration(TransformJPATestConfiguration.class) + @Autowired TransformEngine으로 교체해 해결.
2-4. JSONMessage.java — doSetValue() 수정
doSetValue()의 TYPE_BIGDECIMAL case에 자릿수 검사 추가. 기존에는 자릿수 초과가 getData() 시점에 감지되어 타입 불일치와 발생 시점이 달랐다.
// 수정 전
case Types.TYPE_BIGDECIMAL :
setBigDecimal( itemPath, new BigDecimal(value) );
break;
// 수정 후
case Types.TYPE_BIGDECIMAL :
if (SystemKeys.isValidationEnabled() && !isValid(value, item.getLength(), item.getDecimalPointLength())) {
throw new InvalidAccessException(
String.format("Invalid decimal point format Error value=%s,length=%d,pointLength=%d",
value, item.getLength(), item.getDecimalPointLength()),
itemPath);
}
setBigDecimal( itemPath, new BigDecimal(value) );
break;
@DataJpaTest
@ContextConfiguration(classes = { TransformJPATestConfiguration.class })
@Sql({
"/com/eactive/eai/transformer/init_tseaitr06.sql", // 레이아웃 타입 코드
"/com/eactive/eai/transformer/init_json_validation.sql" // EAI_UJSONTYPE_REQ1 레이아웃
})
3. 테스트 케이스
타입 불일치 — setData() 시점, validation 플래그 무관
| 테스트 메서드 | 입력 | 기대 결과 |
|---|---|---|
testIntFieldTypeError |
"INT_VALUE":"abc" |
MessageSetDataException (cause: NumberFormatException) |
testLongFieldTypeError |
"LONG_VALUE":"not_a_number" |
MessageSetDataException (cause: NumberFormatException) |
testBigDecimalFieldTypeError |
"BIG_VALUE":"invalid_decimal" |
MessageSetDataException (cause: NumberFormatException) |
자릿수 초과 — setData() 시점, transformer.validation=true 필요
| 테스트 메서드 | 입력 | 기대 결과 |
|---|---|---|
testBigDecimalIntegerPartOverflow |
"BIG_VALUE":12345.12345 (정수부 5자리) |
MessageSetDataException ("Invalid decimal point format") |
testBigDecimalFractionalPartOverflow |
"BIG_VALUE":1234.123456 (소수부 6자리) |
MessageSetDataException ("Invalid decimal point format") |
testBigDecimalIntegerOnlyOverflow |
"BIG15_VALUE":1234567890123456 (16자리) |
MessageSetDataException ("Invalid decimal point format") |
testBigDecimalWithinBounds |
"BIG_VALUE":1234.12345 (정수부 4자리, 소수부 5자리) |
정상 처리, 결과 not null |
4. 예외 전파 경로
[타입 불일치 — setData() 시점]
setData(json)
└─ doSetData()
└─ doSetValue()
└─ new Integer/Long/BigDecimal(value) ← NumberFormatException
└─ setValue() wraps → InvalidAccessException
└─ doSetData() wraps → MessageSetDataException
[자릿수 초과 — setData() 시점, validation=true]
setData(json)
└─ doSetData()
└─ doSetValue()
└─ isValid() false → throw InvalidAccessException
└─ setValue() wraps → InvalidAccessException
└─ doSetData() wraps → MessageSetDataException