From 8d69c459d9fdaa7dc68560b57028d105c2069210 Mon Sep 17 00:00:00 2001 From: curry772 Date: Tue, 26 May 2026 16:36:16 +0900 Subject: [PATCH] =?UTF-8?q?=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8?= =?UTF-8?q?=20=EC=9C=A0=EB=9F=89=EC=A0=9C=EC=96=B4=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=8B=A8=EC=9C=84=ED=85=8C=EC=8A=A4=ED=8A=B8=20eapim-online=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReloadInflowClientControlCommandTest.java | 108 ++++++++++++++++++ .../RemoveInflowClientControlCommandTest.java | 101 ++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java create mode 100644 src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java diff --git a/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java b/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java new file mode 100644 index 0000000..0e2021f --- /dev/null +++ b/src/test/java/com/eactive/eai/agent/inflow/ReloadInflowClientControlCommandTest.java @@ -0,0 +1,108 @@ +package com.eactive.eai.agent.inflow; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.agent.command.ReloadInflowClientControlCommand; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.custom.inflow.ClientDualInflowControlManager; + +/** + * ReloadInflowClientControlCommand 단위 테스트. + * + *

InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여 + * PropManager/ApplicationContext 없이 동작을 검증한다. + */ +class ReloadInflowClientControlCommandTest { + + private ClientDualInflowControlManager mockDualManager; + + @BeforeEach + void setUp() { + mockDualManager = mock(ClientDualInflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + @AfterEach + void tearDown() { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + private ReloadInflowClientControlCommand commandWith(Object args) { + ReloadInflowClientControlCommand cmd = new ReloadInflowClientControlCommand(); + cmd.setArgs(args); + return cmd; + } + + // ========================================================================= + // args 타입 검증 실패 + // ========================================================================= + + @Test + void execute_argsIsInteger_throwsCommandException() { + // args 검증이 getInflowControlManager() 호출 이전에 발생하므로 캐시 설정 불필요 + assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute); + } + + // ========================================================================= + // ClientDualInflowControlManager 비활성 + // ========================================================================= + + @Test + void execute_notClientDualManager_throwsCommandException() { + InflowControlManager baseMgr = mock(InflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr); + + assertThrows(CommandException.class, commandWith("CLIENT_A")::execute); + } + + // ========================================================================= + // 전체 재로드 (ALL) + // ========================================================================= + + @Test + void execute_argsIsALL_callsReloadClientNoArgs() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("ALL").execute(); + + assertEquals("success", result); + verify(mockDualManager).reloadClient(); + verify(mockDualManager, never()).reloadClient(anyString()); + } + + // ========================================================================= + // 개별 재로드 (ClientId) + // ========================================================================= + + @Test + void execute_argsIsClientId_callsReloadClientWithId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("CLIENT_A").execute(); + + assertEquals("success", result); + verify(mockDualManager).reloadClient("CLIENT_A"); + verify(mockDualManager, never()).reloadClient(); + } + + @Test + void execute_differentClientId_callsReloadClientWithThatId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_B").execute(); + + verify(mockDualManager).reloadClient("CLIENT_B"); + } +} diff --git a/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java b/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java new file mode 100644 index 0000000..940d8da --- /dev/null +++ b/src/test/java/com/eactive/eai/agent/inflow/RemoveInflowClientControlCommandTest.java @@ -0,0 +1,101 @@ +package com.eactive.eai.agent.inflow; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.agent.command.RemoveInflowClientControlCommand; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.custom.inflow.ClientDualInflowControlManager; + +/** + * RemoveInflowClientControlCommand 단위 테스트. + * + *

InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여 + * PropManager/ApplicationContext 없이 동작을 검증한다. + */ +class RemoveInflowClientControlCommandTest { + + private ClientDualInflowControlManager mockDualManager; + + @BeforeEach + void setUp() { + mockDualManager = mock(ClientDualInflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + @AfterEach + void tearDown() { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null); + } + + private RemoveInflowClientControlCommand commandWith(Object args) { + RemoveInflowClientControlCommand cmd = new RemoveInflowClientControlCommand(); + cmd.setArgs(args); + return cmd; + } + + // ========================================================================= + // args 타입 검증 실패 + // ========================================================================= + + @Test + void execute_argsIsInteger_throwsCommandException() { + assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute); + } + + // ========================================================================= + // ClientDualInflowControlManager 비활성 + // ========================================================================= + + @Test + void execute_notClientDualManager_throwsCommandException() { + InflowControlManager baseMgr = mock(InflowControlManager.class); + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr); + + assertThrows(CommandException.class, commandWith("CLIENT_A")::execute); + } + + // ========================================================================= + // 정상 제거 + // ========================================================================= + + @Test + void execute_validClientId_callsRemoveClient() throws CommandException { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + Object result = commandWith("CLIENT_A").execute(); + + assertEquals("success", result); + verify(mockDualManager).removeClient("CLIENT_A"); + } + + @Test + void execute_differentClientId_callsRemoveClientWithThatId() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_B").execute(); + + verify(mockDualManager).removeClient("CLIENT_B"); + } + + @Test + void execute_validClientId_doesNotCallReload() throws Exception { + ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager); + + commandWith("CLIENT_A").execute(); + + verify(mockDualManager, never()).reloadClient(); + verify(mockDualManager, never()).reloadClient(anyString()); + } +}