# 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` 시스템 프로퍼티를 읽어 필드에 저장하지만 반환값에 반영되지 않았다. ```java // 수정 전 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()` 시점에 감지되어 타입 불일치와 발생 시점이 달랐다. ```java // 수정 전 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 ```