알림 생성 기능 구현을 완료하고 기능이 정상적으로 동작하는지 확인하기 위한 테스트 코드 작성을 진행했다.
이벤트 리스너를 테스트하기 위해 이벤트를 발행한 후 리스너에서 해당 이벤트가 처리가 완료되어 동일한 내용으로 알림이 저장 됐는지 확인했다. 하지만 알림 발행이 완료되고 알림을 조회했을 때 알림이 존재하지 않는 것으로 확인됐다.
원인을 파악해보니 리스너에서 @EventListener를 사용할 때 메서드가 suspend 일 경우 이벤트를 수신받지 못 하는 것으로 판단됐다. 이를 해결하기 위해 suspend를 제거하고 메서드에서CoroutineScope를 사용하도록 수정하니 정상적으로 동작하는 것을 확인했다.
그 다음으로 발생한 문제는 이벤트 발행 후 곧바로 데이터를 조회할 경우 데이터가 조회되지 않는 문제가 발생했다. 이벤트를 발행한 후에 delay 함수를 사용하여 100ms를 지연시켜 테스트가 성공하는 것을 확인했다. delay로 검증을 지연시키는 것 이외에 좋은 테스트 방법을 찾아봤을 때 썩 괜찮은 방법이 발견되지는 않았다. 추후에 괜찮은 테스트 방법을 찾게 되면 적용해보도록 하자.
@Testfun`도메인 생성 이벤트를 처리할 수 있다`(): Unit=runBlocking {// givenval expected =CreateReviewEvent( receiverId = UUID.randomUUID(), reviewId = UUID.randomUUID(), reviewerName ="reviewerName", postId = UUID.randomUUID(), postTitle ="postTitle", writtenDate = Instant.now(), )// when applicationEventPublisher.publishEvent(expected)delay(100)// thenval notifications = notificationRepository.findAll().toList()val actual = notifications[0]assertThat(notifications.size).isOne()assertThat(actual.content).isEqualTo(expected.content)assertThat(actual.note).isEqualTo(expected.createNote())assertThat(actual.receiverId).isEqualTo(expected.receiverId)}
회고 글을 작성하면서 코드를 살펴보다 보니 CoroutineScope를 통해 스코프를 생성하고 launch로 코루틴을 실행할 경우 예외가 발생했을 때 에러가 로깅되지 않을 것으로 판단됐다. 이를 위해 로깅도 추가해서 적용해보도록 하자.
실시간 알림 조회 구현
알림 생성 기능의 테스트 코드 구현을 마치고 실시간 알림 개수를 조회 기능을 구현했다.
실시간 조회를 위해 처음 사용해보는 Spring SSE를 사용했으나, 구현 방식은 기존의 REST 구현 방식과 동일하여 쉽게 구현할 수 있었다.