diff --git a/src/test/java/com/eactive/eai/MessageKeyTest.java b/src/test/java/com/eactive/eai/MessageKeyTest.java
new file mode 100644
index 0000000..c7f2a12
--- /dev/null
+++ b/src/test/java/com/eactive/eai/MessageKeyTest.java
@@ -0,0 +1,380 @@
+package com.eactive.eai;
+
+import com.eactive.eai.common.EAITable;
+import com.eactive.eai.common.util.MessageUtil;
+import org.json.simple.JSONValue;
+
+/**
+ * 테스트용 메시지 키 검증 클래스
+ */
+public class MessageKeyTest {
+
+
+ /**
+ * XML 또는 JSON 메시지의 성공 여부를 검증하는 테스트용 메소드
+ * 추출된 값을 배열로 반환
+ */
+ public static TestResult isSuccessMessageTest(String messageType, Object message, String path, String expectedValue) {
+ try {
+ String extractedValue = "";
+
+ if(EAITable.XML_TYPE.equals(messageType)) {
+ if(message instanceof byte[]) {
+ extractedValue = extractXmlValue(new String((byte[])message), path);
+ } else if(message instanceof String) {
+ extractedValue = extractXmlValue((String)message, path);
+ }
+ }
+ else if(EAITable.JSON_TYPE.equals(messageType)) {
+ Object json = JSONValue.parse((String)message);
+ extractedValue = extractJsonValue(json, path);
+ }
+
+ if(extractedValue == null) extractedValue = "";
+ boolean result = compareMessageValue(extractedValue, expectedValue);
+
+ return new TestResult(result, extractedValue);
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ return new TestResult(false, "오류 발생: " + e.getMessage());
+ }
+ }
+
+ // 테스트 결과를 담는 클래스
+ static class TestResult {
+ boolean success;
+ String extractedValue;
+
+ TestResult(boolean success, String extractedValue) {
+ this.success = success;
+ this.extractedValue = extractedValue;
+ }
+ }
+
+ /**
+ * 메시지 값 비교를 수행하는 메소드
+ */
+ private static boolean compareMessageValue(String actualValue, String expectedValue) {
+ if(actualValue == null) actualValue = "";
+ if(expectedValue == null) return false;
+
+ // 예약어로 시작하는 경우
+ if(expectedValue.startsWith("@")) {
+ return compareWithReservedWord(actualValue, expectedValue);
+ }
+
+ // 일반 equals 비교
+ return actualValue.equals(expectedValue);
+ }
+
+ /**
+ * 예약어를 포함한 값 비교 처리
+ */
+ private static boolean compareWithReservedWord(String actualValue, String definition) {
+ if (actualValue == null) actualValue = "";
+ if (definition == null) return false;
+
+ try {
+ // 1. 기본 비교
+ if (definition.startsWith("@eq:")) {
+ return actualValue.equals(definition.substring(4));
+ }
+ if (definition.startsWith("@ne:")) {
+ return !actualValue.equals(definition.substring(4));
+ }
+ if ("@null".equals(definition)) {
+ return actualValue.isEmpty();
+ }
+ if ("@!null".equals(definition)) {
+ return !actualValue.isEmpty();
+ }
+
+ // 2. 문자열 패턴
+ if (definition.startsWith("@contains:")) {
+ String[] values = definition.substring(10).split(",");
+ for (String value : values) {
+ if (actualValue.equals(value.trim())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (definition.startsWith("@!contains:")) {
+ String[] values = definition.substring(11).split(",");
+ for (String value : values) {
+ if (actualValue.equals(value.trim())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (definition.startsWith("@starts:")) {
+ return actualValue.startsWith(definition.substring(8));
+ }
+ if (definition.startsWith("@ends:")) {
+ return actualValue.endsWith(definition.substring(6));
+ }
+
+ // 3. 숫자 비교
+ if (definition.startsWith("@gt:") ||
+ definition.startsWith("@lt:") ||
+ definition.startsWith("@ge:") ||
+ definition.startsWith("@le:")) {
+
+ double actualNum = Double.parseDouble(actualValue);
+ if (definition.startsWith("@gt:")) {
+ double defNum = Double.parseDouble(definition.substring(4));
+ return actualNum > defNum;
+ }
+ if (definition.startsWith("@lt:")) {
+ double defNum = Double.parseDouble(definition.substring(4));
+ return actualNum < defNum;
+ }
+ if (definition.startsWith("@ge:")) {
+ double defNum = Double.parseDouble(definition.substring(4));
+ return actualNum >= defNum;
+ }
+ if (definition.startsWith("@le:")) {
+ double defNum = Double.parseDouble(definition.substring(4));
+ return actualNum <= defNum;
+ }
+ }
+
+ return false;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * XML 값 추출 메소드
+ */
+ private static String extractXmlValue(String xmlMessage, String path) {
+ if(path == null) return "";
+
+ // XPath 형식인 경우
+ if(path.startsWith("//") || path.startsWith("/")) {
+ return MessageUtil.getXmlFldByXPath(xmlMessage, path);
+ }
+
+ // 단순 태그명인 경우
+ return MessageUtil.getXmlFld(xmlMessage, path);
+ }
+
+ /**
+ * JSON 값 추출 메소드
+ */
+ private static String extractJsonValue(Object json, String path) {
+ if(path == null) return "";
+
+ // JSONPath 형식인 경우
+ if(path.startsWith("$.")) {
+ return MessageUtil.getJSONValueByPath(json, path);
+ }
+
+ // 단순 키인 경우
+ return MessageUtil.getJSONValue(json, path);
+ }
+
+ private static void testXml() {
+ // System.out.println("\n=== XML 테스트 ===");
+
+ // 단순 경로 테스트
+ String xml1 = "SUCCESS";
+ test("XML 단순 경로",
+ EAITable.XML_TYPE,
+ xml1,
+ "status",
+ "SUCCESS");
+
+ // 중첩 경로 테스트 (일반 방식)
+ String xml2 = "";
+ test("XML 중첩 경로 (일반)",
+ EAITable.XML_TYPE,
+ xml2,
+ "resultCode",
+ "0000");
+
+ // 중첩 경로 테스트 (XPath 방식)
+ test("XML 중첩 경로 (XPath)",
+ EAITable.XML_TYPE,
+ xml2,
+ "//response/header/resultCode",
+ "0000");
+
+ // 네임스페이스가 있는 XML
+ String xml3 = "OK";
+ test("XML 네임스페이스",
+ EAITable.XML_TYPE,
+ xml3,
+ "//ns:status",
+ "OK");
+
+ // 실패 케이스
+ test("XML 실패 케이스",
+ EAITable.XML_TYPE,
+ xml1,
+ "status",
+ "FAIL");
+
+ // 존재하지 않는 경로
+ test("XML 없는 경로",
+ EAITable.XML_TYPE,
+ xml1,
+ "nonexistent",
+ "SUCCESS");
+ }
+
+ private static void testJson() {
+ // System.out.println("\n=== JSON 테스트 ===");
+
+ // 단순 경로 테스트
+ String json1 = "{\"status\":\"success\"}";
+ test("JSON 단순 경로",
+ EAITable.JSON_TYPE,
+ json1,
+ "status",
+ "success");
+
+ // 중첩 경로 테스트 (일반 방식)
+ String json2 = "{\"response\":{\"header\":{\"resultCode\":\"0000\"}}}";
+ test("JSON 중첩 경로 (일반)",
+ EAITable.JSON_TYPE,
+ json2,
+ "resultCode",
+ "0000");
+
+ // 중첩 경로 테스트 (JSONPath 방식)
+ test("JSON 중첩 경로 (JSONPath)",
+ EAITable.JSON_TYPE,
+ json2,
+ "$.response.header.resultCode",
+ "0000");
+
+ // 배열이 포함된 JSON
+ String json3 = "{\"responses\":[{\"status\":\"success\"},{\"status\":\"pending\"}]}";
+ test("JSON 배열 경로",
+ EAITable.JSON_TYPE,
+ json3,
+ "$.responses[0].status",
+ "success");
+
+ // 실패 케이스
+ test("JSON 실패 케이스",
+ EAITable.JSON_TYPE,
+ json1,
+ "status",
+ "failure");
+
+ // 존재하지 않는 경로
+ test("JSON 없는 경로",
+ EAITable.JSON_TYPE,
+ json1,
+ "nonexistent",
+ "success");
+ }
+
+ public static void main(String[] args) {
+ testXml();
+ testJson();
+ testReservedWords();
+ }
+
+ private static void testReservedWords() {
+ // System.out.println("\n=== 예약어 테스트 ===");
+
+ // 1. 기본 비교 테스트
+ test("예약어 - eq",
+ EAITable.XML_TYPE,
+ "SUCCESS",
+ "code",
+ "@eq:SUCCESS");
+
+ test("예약어 - ne",
+ EAITable.XML_TYPE,
+ "SUCCESS",
+ "code",
+ "@ne:FAIL");
+
+ test("예약어 - null",
+ EAITable.XML_TYPE,
+ "",
+ "code",
+ "@null");
+
+ test("예약어 - !null",
+ EAITable.XML_TYPE,
+ "SUCCESS",
+ "code",
+ "@!null");
+
+ // 2. 문자열 패턴 테스트
+ test("예약어 - contains",
+ EAITable.JSON_TYPE,
+ "{\"status\":\"success\"}",
+ "status",
+ "@contains:success,ok,done");
+
+ test("예약어 - !contains",
+ EAITable.JSON_TYPE,
+ "{\"status\":\"success\"}",
+ "status",
+ "@!contains:fail,error,invalid");
+
+ test("예약어 - starts",
+ EAITable.JSON_TYPE,
+ "{\"code\":\"SUCCESS_001\"}",
+ "code",
+ "@starts:SUCCESS");
+
+ test("예약어 - ends",
+ EAITable.JSON_TYPE,
+ "{\"code\":\"ERR_001\"}",
+ "code",
+ "@ends:001");
+
+ // 3. 숫자 비교 테스트
+ test("예약어 - gt",
+ EAITable.JSON_TYPE,
+ "{\"value\":\"100\"}",
+ "value",
+ "@gt:50");
+
+ test("예약어 - lt",
+ EAITable.JSON_TYPE,
+ "{\"value\":\"100\"}",
+ "value",
+ "@lt:150");
+
+ test("예약어 - ge",
+ EAITable.JSON_TYPE,
+ "{\"value\":\"100\"}",
+ "value",
+ "@ge:100");
+
+ test("예약어 - le",
+ EAITable.JSON_TYPE,
+ "{\"value\":\"100\"}",
+ "value",
+ "@le:100");
+
+ // 4. 실패 케이스
+ test("예약어 - 잘못된 숫자",
+ EAITable.JSON_TYPE,
+ "{\"value\":\"invalid\"}",
+ "value",
+ "@gt:50");
+
+ test("예약어 - 잘못된 패턴",
+ EAITable.JSON_TYPE,
+ "{\"status\":\"success\"}",
+ "status",
+ "@invalid:pattern");
+ }
+
+ private static void test(String testName, String type, String message, String path, String expected) {
+ TestResult result = isSuccessMessageTest(type, message, path, expected);
+ // System.out.println(String.format( "테스트: %s\n결과: %s\n메시지: %s\n경로: %s\n기대값: %s\n추출된 값: [%s]\n",testName, result.success ? "성공" : "실패",message,path,expected,result.extractedValue ));
+ }
+}
\ No newline at end of file