WebSocketSession Mock 테스트 내 중복 제거
기존에는 특정 테스트 클래스 내에 테스트 상황을 모두 가정해놓고 테스트를 진행하였습니다. 그렇다보니 여러 테스트 클래스에서 동시에 사용되는 부분이 있어 중복이 발생하였습니다. 그러한 부분을 제거하고자 하였습니다.
BasicAuthAcceptanceTest
라는 클래스가 있습니다. 이 클래스의 역할은 스프링 테스트 서버를 가동시키고 특정 유저를 찾아 세션값 까지 넣는 역할을 합니다. 즉, 세션값으로 수행하는 로직이 있을 때 사용하는데요. 저는 BasicAuthAcceptanceTest
을 상속받는 클래스를 하나 더 만들어서 여기엔 WebSocketSession
에 대한 테스트 데이터를 미리 만들어서 중복을 해결하려고 합니다.
public abstract class WebSocketSessionTest extends BasicAuthAcceptanceTest {
protected GameRoom gameRoom = GameRoom.create("test방");
protected WebSocketSession webSocketSession = mock(WebSocketSession.class);
@Autowired
private GameRoomRepository gameRoomRepository;
@Before
public void setUp() throws Exception {
Map<String, Object> map = new HashMap<>();
gameRoomRepository.save(gameRoom);
map.put(USER_SESSION_KEY, loginUser);
map.put(GAME_SESSION_KEY, gameRoom.getId());
when(webSocketSession.getAttributes()).thenReturn(map);
}
}
BasicAuthAcceptanceTest
을 통해 loginUser 라는 User
객체가 상위 클래스에 있기 때문에 재사용할 수 있구요. GameRoom 관해서는 이쪽에서 따로 만들어서 GameRoomRepository
에도 넣고 Mock에도 그 방을 찾을 수 있는 id를 넣어두었습니다. 결국 이를 상속받는 하위 클래스에서 테스트를 이렇게 진행할 수 있는 것이죠.
@Test
public void supportsParameter() {
assertThat(gameRoomHandlerMethodArgumentResolver.supportsParameter(GameRoom.class)).isTrue();
}
@Test
public void resolveArgument() {
MessageDto messageDto = new MessageDto();
messageDto.setWebSocketSession(webSocketSession);
assertThat(gameRoomHandlerMethodArgumentResolver.resolveArgument(messageDto)).isEqualTo(gameRoom);
}
이제는 WebSocketSession 관련해서는 이에 대한 Mock이 있는 WebSocketSessionTest
을 상속하여 테스트가 가능해졌습니다!
파라미터 수 줄이기
현재 파라미터 바인딩 해줄 수 있는(파라미터에 의존성을 주입하는) 클래스를 3개를 만들었습니다. GameRoom
, User
, WebSocketSession
이렇게 3개의 객체에 관해서인데요. 그런데 사실 GameRoom
, User
이 WebSocketSession
의 정보를 이용해서 만드는 객체입니다. 그렇다보니 다 만들고 나서 'WebSocketSession
만 만들면 될걸 왜 굳이 다 만들었을까' 라는 의문이 스스로 들었습니다.
그래서 일단 만들어놓았으니 그대로 두고 GameRoom
에 대해선 GameService
내의 GameRoomRepository
로 찾아올 수 있으니 Controllerd에서 바로 받지 않는 방향으로 일단 해보려합니다. User
까지는 사실 WebSocketSession
으로 할 수는 있지만 너무 자주 사용되는거라 중복이 많이 발생할 것 같아서요. 최초 Join 때 이후로는 WebSocketSession
객체를 쓸 일이 없어 GameRoom
바라미터 바인딩 된 거만 쓰면 되는데 그럼 GameService
내에 GameRoomRepository
의 의미가 없어질 것 같아 위와 같은 방향대로 하려고 합니다.
소켓메시지로부터 컨트롤러 연결
[ERROR] [http-nio-8080-exec-9] [o.s.w.s.h.ExceptionWebSocketHandlerDecorator] - Closing session due to exception for WebSocketServerSockJsSession[id=z1co4am0]
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "requestMethod" (class lasermaze.socket.MessageType), not marked as ignorable (0 known properties: ])
at [Source: (String)"{"path":"/join","requestMethod":"POST"}"; line: 1, column: 34] (through reference chain: lasermaze.socket.MessageType["requestMethod"])
현재 이런 오류 메시지가 발생했습니다. Jackson을 사용하여 String의 메시지를 읽어 객체로 만드는 과정에서 제가 스프링 어노테이션을 사용하다보니 객체 만드는데 오류가 발생한 것 같네요. 이 부분은 좀 더 탐구해봐야겠습니다.
'TIL' 카테고리의 다른 글
TIL(2019-12-15) (0) | 2019.12.16 |
---|---|
Today's Dev Notes(2019-03-17) (0) | 2019.03.17 |
Todays' Dev Notes(2018-03-15) (0) | 2019.03.16 |
Todays' Dev Notes(2018-03-11) (0) | 2019.03.12 |
Today's Dev Notes(2019-03-10) (0) | 2019.03.11 |