Files
elink-online-transformer/JSON_VALIDATION_TEST_PLAN.md
curry772 0e40c71a9d BigDecimal 자릿수 검사를 doSetValue() 시점으로 이동
- 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>
2026-04-23 09:47:04 +09:00

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.javadoSetValue() 수정

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