test: ReloadInflowClientControlCommandTest / RemoveInflowClientControlCommandTest 수정

PropManager NPE 및 정적 캐시 미초기화로 인한 테스트 실패 수정.
InflowControlUtil.cachedInflowControlManager를 ReflectionTestUtils로
직접 주입/초기화하는 방식으로 변경.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
curry772
2026-04-30 10:15:27 +09:00
parent 496bdd1468
commit 437961e7d5
2 changed files with 33 additions and 36 deletions
@@ -3,32 +3,35 @@ package com.eactive.eai.agent.inflow;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import com.eactive.eai.agent.command.CommandException; import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.inflow.InflowControlManager; import com.eactive.eai.common.inflow.InflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager; import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
import com.eactive.eai.common.util.ApplicationContextProvider;
/** /**
* ReloadInflowClientControlCommand 단위 테스트. * ReloadInflowClientControlCommand 단위 테스트.
* *
* <p>ApplicationContextProvider의 static context 필드에 mock ApplicationContext를 주입하여 * <p>InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여
* InflowControlManager.getInstance() 반환값을 제어한다. * PropManager/ApplicationContext 없이 동작을 검증한다.
*/ */
class ReloadInflowClientControlCommandTest { class ReloadInflowClientControlCommandTest {
private ApplicationContext mockContext;
private DualInflowControlManager mockDualManager; private DualInflowControlManager mockDualManager;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
mockContext = mock(ApplicationContext.class);
mockDualManager = mock(DualInflowControlManager.class); mockDualManager = mock(DualInflowControlManager.class);
ReflectionTestUtils.setField(ApplicationContextProvider.class, "context", mockContext); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null);
}
@AfterEach
void tearDown() {
ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null);
} }
private ReloadInflowClientControlCommand commandWith(Object args) { private ReloadInflowClientControlCommand commandWith(Object args) {
@@ -43,10 +46,8 @@ class ReloadInflowClientControlCommandTest {
@Test @Test
void execute_argsIsInteger_throwsCommandException() { void execute_argsIsInteger_throwsCommandException() {
ReloadInflowClientControlCommand cmd = commandWith(Integer.valueOf(1)); // args 검증이 getInflowControlManager() 호출 이전에 발생하므로 캐시 설정 불필요
assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute);
assertThrows(CommandException.class, cmd::execute);
verifyNoInteractions(mockContext);
} }
// ========================================================================= // =========================================================================
@@ -56,11 +57,9 @@ class ReloadInflowClientControlCommandTest {
@Test @Test
void execute_notDualManager_throwsCommandException() { void execute_notDualManager_throwsCommandException() {
InflowControlManager baseMgr = mock(InflowControlManager.class); InflowControlManager baseMgr = mock(InflowControlManager.class);
when(mockContext.getBean(InflowControlManager.class)).thenReturn(baseMgr); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr);
ReloadInflowClientControlCommand cmd = commandWith("CLIENT_A"); assertThrows(CommandException.class, commandWith("CLIENT_A")::execute);
assertThrows(CommandException.class, cmd::execute);
} }
// ========================================================================= // =========================================================================
@@ -69,7 +68,7 @@ class ReloadInflowClientControlCommandTest {
@Test @Test
void execute_argsIsALL_callsReloadClientNoArgs() throws Exception { void execute_argsIsALL_callsReloadClientNoArgs() throws Exception {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
Object result = commandWith("ALL").execute(); Object result = commandWith("ALL").execute();
@@ -84,7 +83,7 @@ class ReloadInflowClientControlCommandTest {
@Test @Test
void execute_argsIsClientId_callsReloadClientWithId() throws Exception { void execute_argsIsClientId_callsReloadClientWithId() throws Exception {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
Object result = commandWith("CLIENT_A").execute(); Object result = commandWith("CLIENT_A").execute();
@@ -95,7 +94,7 @@ class ReloadInflowClientControlCommandTest {
@Test @Test
void execute_differentClientId_callsReloadClientWithThatId() throws Exception { void execute_differentClientId_callsReloadClientWithThatId() throws Exception {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
commandWith("CLIENT_B").execute(); commandWith("CLIENT_B").execute();
@@ -3,32 +3,35 @@ package com.eactive.eai.agent.inflow;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import com.eactive.eai.agent.command.CommandException; import com.eactive.eai.agent.command.CommandException;
import com.eactive.eai.common.inflow.InflowControlManager; import com.eactive.eai.common.inflow.InflowControlManager;
import com.eactive.eai.common.inflow.InflowControlUtil;
import com.eactive.eai.common.inflow.dual.DualInflowControlManager; import com.eactive.eai.common.inflow.dual.DualInflowControlManager;
import com.eactive.eai.common.util.ApplicationContextProvider;
/** /**
* RemoveInflowClientControlCommand 단위 테스트. * RemoveInflowClientControlCommand 단위 테스트.
* *
* <p>ApplicationContextProvider의 static context 필드에 mock ApplicationContext를 주입하여 * <p>InflowControlUtil의 cachedInflowControlManager 필드에 mock을 직접 주입하여
* InflowControlManager.getInstance() 반환값을 제어한다. * PropManager/ApplicationContext 없이 동작을 검증한다.
*/ */
class RemoveInflowClientControlCommandTest { class RemoveInflowClientControlCommandTest {
private ApplicationContext mockContext;
private DualInflowControlManager mockDualManager; private DualInflowControlManager mockDualManager;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
mockContext = mock(ApplicationContext.class);
mockDualManager = mock(DualInflowControlManager.class); mockDualManager = mock(DualInflowControlManager.class);
ReflectionTestUtils.setField(ApplicationContextProvider.class, "context", mockContext); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null);
}
@AfterEach
void tearDown() {
ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", null);
} }
private RemoveInflowClientControlCommand commandWith(Object args) { private RemoveInflowClientControlCommand commandWith(Object args) {
@@ -43,10 +46,7 @@ class RemoveInflowClientControlCommandTest {
@Test @Test
void execute_argsIsInteger_throwsCommandException() { void execute_argsIsInteger_throwsCommandException() {
RemoveInflowClientControlCommand cmd = commandWith(Integer.valueOf(1)); assertThrows(CommandException.class, commandWith(Integer.valueOf(1))::execute);
assertThrows(CommandException.class, cmd::execute);
verifyNoInteractions(mockContext);
} }
// ========================================================================= // =========================================================================
@@ -56,11 +56,9 @@ class RemoveInflowClientControlCommandTest {
@Test @Test
void execute_notDualManager_throwsCommandException() { void execute_notDualManager_throwsCommandException() {
InflowControlManager baseMgr = mock(InflowControlManager.class); InflowControlManager baseMgr = mock(InflowControlManager.class);
when(mockContext.getBean(InflowControlManager.class)).thenReturn(baseMgr); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", baseMgr);
RemoveInflowClientControlCommand cmd = commandWith("CLIENT_A"); assertThrows(CommandException.class, commandWith("CLIENT_A")::execute);
assertThrows(CommandException.class, cmd::execute);
} }
// ========================================================================= // =========================================================================
@@ -69,7 +67,7 @@ class RemoveInflowClientControlCommandTest {
@Test @Test
void execute_validClientId_callsRemoveClient() throws CommandException { void execute_validClientId_callsRemoveClient() throws CommandException {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
Object result = commandWith("CLIENT_A").execute(); Object result = commandWith("CLIENT_A").execute();
@@ -79,7 +77,7 @@ class RemoveInflowClientControlCommandTest {
@Test @Test
void execute_differentClientId_callsRemoveClientWithThatId() throws Exception { void execute_differentClientId_callsRemoveClientWithThatId() throws Exception {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
commandWith("CLIENT_B").execute(); commandWith("CLIENT_B").execute();
@@ -88,7 +86,7 @@ class RemoveInflowClientControlCommandTest {
@Test @Test
void execute_validClientId_doesNotCallReload() throws Exception { void execute_validClientId_doesNotCallReload() throws Exception {
when(mockContext.getBean(InflowControlManager.class)).thenReturn(mockDualManager); ReflectionTestUtils.setField(InflowControlUtil.class, "cachedInflowControlManager", mockDualManager);
commandWith("CLIENT_A").execute(); commandWith("CLIENT_A").execute();