完善e2e测试与后端测试,微信小程序端UI层测试暂未完成

This commit was merged in pull request #52.
This commit is contained in:
2026-07-23 20:16:31 +08:00
parent b689656faf
commit 86b7555943
37 changed files with 6819 additions and 5 deletions
@@ -0,0 +1,186 @@
package cn.novalon.gym.manage.notify.core.service.impl;
import cn.novalon.gym.manage.notify.core.domain.Banner;
import cn.novalon.gym.manage.notify.core.repository.IBannerRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDateTime;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class BannerServiceImplTest {
@Mock
private IBannerRepository bannerRepository;
private BannerServiceImpl bannerService;
@BeforeEach
void setUp() {
bannerService = new BannerServiceImpl(bannerRepository);
}
// ==================== getAllBanners ====================
@Test
void getAllBanners_shouldReturnNonDeletedBanners() {
Banner banner = createTestBanner(1L, "轮播图1");
when(bannerRepository.findByDeletedAtIsNull()).thenReturn(Flux.just(banner));
Flux<Banner> result = bannerService.getAllBanners();
StepVerifier.create(result)
.expectNextCount(1)
.verifyComplete();
verify(bannerRepository).findByDeletedAtIsNull();
}
@Test
void getAllBanners_shouldReturnEmptyWhenNone() {
when(bannerRepository.findByDeletedAtIsNull()).thenReturn(Flux.empty());
Flux<Banner> result = bannerService.getAllBanners();
StepVerifier.create(result)
.verifyComplete();
}
// ==================== getActiveBanners ====================
@Test
void getActiveBanners_shouldReturnActiveBanners() {
when(bannerRepository.findActiveBanners()).thenReturn(Flux.just(createTestBanner(1L, "活跃")));
Flux<Banner> result = bannerService.getActiveBanners();
StepVerifier.create(result)
.expectNextCount(1)
.verifyComplete();
verify(bannerRepository).findActiveBanners();
}
// ==================== getBannerById ====================
@Test
void getBannerById_shouldReturnBannerWhenFound() {
when(bannerRepository.findById(1L)).thenReturn(Mono.just(createTestBanner(1L, "轮播图1")));
Mono<Banner> result = bannerService.getBannerById(1L);
StepVerifier.create(result)
.expectNextCount(1)
.verifyComplete();
}
@Test
void getBannerById_shouldReturnEmptyWhenNotFound() {
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
Mono<Banner> result = bannerService.getBannerById(999L);
StepVerifier.create(result)
.verifyComplete();
}
// ==================== createBanner ====================
@Test
void createBanner_shouldSaveAndReturn() {
Banner banner = createTestBanner(null, "新轮播图");
when(bannerRepository.save(any(Banner.class)))
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
Mono<Banner> result = bannerService.createBanner(banner);
StepVerifier.create(result)
.expectNextMatches(b -> b.getTitle().equals("新轮播图") && b.getCreatedAt() != null)
.verifyComplete();
verify(bannerRepository).save(banner);
}
// ==================== updateBanner ====================
@Test
void updateBanner_shouldUpdateAndReturn() {
Banner existing = createTestBanner(1L, "旧标题");
Banner update = createTestBanner(1L, "新标题");
when(bannerRepository.findById(1L)).thenReturn(Mono.just(existing));
when(bannerRepository.save(any(Banner.class)))
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
Mono<Banner> result = bannerService.updateBanner(1L, update);
StepVerifier.create(result)
.expectNextMatches(b -> b.getTitle().equals("新标题") && b.getUpdatedAt() != null)
.verifyComplete();
verify(bannerRepository).save(existing);
}
@Test
void updateBanner_shouldReturnEmptyWhenNotFound() {
Banner update = createTestBanner(999L, "新标题");
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
Mono<Banner> result = bannerService.updateBanner(999L, update);
StepVerifier.create(result)
.verifyComplete();
verify(bannerRepository, never()).save(any());
}
// ==================== deleteBanner ====================
@Test
void deleteBanner_shouldSoftDelete() {
Banner existing = createTestBanner(1L, "轮播图1");
when(bannerRepository.findById(1L)).thenReturn(Mono.just(existing));
when(bannerRepository.save(any(Banner.class))).thenReturn(Mono.just(existing));
Mono<Void> result = bannerService.deleteBanner(1L);
StepVerifier.create(result)
.verifyComplete();
verify(bannerRepository).save(existing);
assertThat(existing.getDeletedAt()).isNotNull();
}
@Test
void deleteBanner_shouldCompleteEmptyWhenNotFound() {
when(bannerRepository.findById(999L)).thenReturn(Mono.empty());
Mono<Void> result = bannerService.deleteBanner(999L);
StepVerifier.create(result)
.verifyComplete();
}
// ==================== helper ====================
private Banner createTestBanner(Long id, String title) {
Banner banner = new Banner();
banner.setId(id);
banner.setImageUrl("https://example.com/banner.jpg");
banner.setTitle(title);
banner.setSubtitle("副标题");
banner.setSortOrder(1);
banner.setIsActive("1");
banner.setCreatedAt(LocalDateTime.now());
return banner;
}
}
@@ -0,0 +1,170 @@
package cn.novalon.gym.manage.notify.core.service.impl;
import cn.novalon.gym.manage.notify.core.domain.SysNotice;
import cn.novalon.gym.manage.notify.core.repository.ISysNoticeRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class SysNoticeServiceImplTest {
@Mock
private ISysNoticeRepository noticeRepository;
private SysNoticeServiceImpl noticeService;
@BeforeEach
void setUp() {
noticeService = new SysNoticeServiceImpl(noticeRepository);
}
// ==================== getAllNotices ====================
@Test
void getAllNotices_shouldReturnNonDeletedNotices() {
SysNotice notice = createTestNotice(1L, "公告1");
when(noticeRepository.findByDeletedAtIsNull()).thenReturn(Flux.just(notice));
Flux<SysNotice> result = noticeService.getAllNotices();
StepVerifier.create(result)
.expectNextMatches(n -> n.getId().equals(1L) && n.getNoticeTitle().equals("公告1"))
.verifyComplete();
verify(noticeRepository).findByDeletedAtIsNull();
}
@Test
void getAllNotices_shouldReturnEmptyWhenNone() {
when(noticeRepository.findByDeletedAtIsNull()).thenReturn(Flux.empty());
Flux<SysNotice> result = noticeService.getAllNotices();
StepVerifier.create(result)
.verifyComplete();
}
// ==================== getNoticeById ====================
@Test
void getNoticeById_shouldReturnNoticeWhenFound() {
SysNotice notice = createTestNotice(1L, "公告1");
when(noticeRepository.findById(1L)).thenReturn(Mono.just(notice));
Mono<SysNotice> result = noticeService.getNoticeById(1L);
StepVerifier.create(result)
.expectNextMatches(n -> n.getId().equals(1L))
.verifyComplete();
}
@Test
void getNoticeById_shouldReturnEmptyWhenNotFound() {
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
Mono<SysNotice> result = noticeService.getNoticeById(999L);
StepVerifier.create(result)
.verifyComplete();
}
// ==================== createNotice ====================
@Test
void createNotice_shouldSaveAndReturnNotice() {
SysNotice notice = createTestNotice(null, "新公告");
when(noticeRepository.save(any(SysNotice.class)))
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
Mono<SysNotice> result = noticeService.createNotice(notice);
StepVerifier.create(result)
.expectNextMatches(n -> n.getNoticeTitle().equals("新公告"))
.verifyComplete();
verify(noticeRepository).save(notice);
}
// ==================== updateNotice ====================
@Test
void updateNotice_shouldUpdateAndReturn() {
SysNotice existing = createTestNotice(1L, "旧标题");
SysNotice update = createTestNotice(1L, "新标题");
when(noticeRepository.findById(1L)).thenReturn(Mono.just(existing));
when(noticeRepository.save(any(SysNotice.class)))
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
Mono<SysNotice> result = noticeService.updateNotice(1L, update);
StepVerifier.create(result)
.expectNextMatches(n -> n.getNoticeTitle().equals("新标题"))
.verifyComplete();
verify(noticeRepository).save(existing);
}
@Test
void updateNotice_shouldReturnEmptyWhenNotFound() {
SysNotice update = createTestNotice(999L, "新标题");
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
Mono<SysNotice> result = noticeService.updateNotice(999L, update);
StepVerifier.create(result)
.verifyComplete();
verify(noticeRepository, never()).save(any());
}
// ==================== deleteNotice ====================
@Test
void deleteNotice_shouldSoftDelete() {
SysNotice existing = createTestNotice(1L, "公告1");
when(noticeRepository.findById(1L)).thenReturn(Mono.just(existing));
when(noticeRepository.save(any(SysNotice.class))).thenReturn(Mono.just(existing));
Mono<Void> result = noticeService.deleteNotice(1L);
StepVerifier.create(result)
.verifyComplete();
verify(noticeRepository).save(existing);
assertThat(existing.getDeletedAt()).isNotNull();
}
@Test
void deleteNotice_shouldCompleteEmptyWhenNotFound() {
when(noticeRepository.findById(999L)).thenReturn(Mono.empty());
Mono<Void> result = noticeService.deleteNotice(999L);
StepVerifier.create(result)
.verifyComplete();
verify(noticeRepository, never()).save(any());
}
// ==================== helper ====================
private SysNotice createTestNotice(Long id, String title) {
SysNotice notice = new SysNotice();
notice.setId(id);
notice.setNoticeTitle(title);
notice.setNoticeContent("公告内容");
notice.setNoticeType("1");
notice.setStatus("1");
return notice;
}
}
@@ -0,0 +1,195 @@
package cn.novalon.gym.manage.notify.core.service.impl;
import cn.novalon.gym.manage.notify.core.domain.SysUserMessage;
import cn.novalon.gym.manage.notify.core.repository.ISysUserMessageRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDateTime;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class SysUserMessageServiceImplTest {
@Mock
private ISysUserMessageRepository messageRepository;
private SysUserMessageServiceImpl messageService;
@BeforeEach
void setUp() {
messageService = new SysUserMessageServiceImpl(messageRepository);
}
// ==================== getMessagesByUser ====================
@Test
void getMessagesByUser_shouldReturnMessages() {
List<SysUserMessage> messages = List.of(createTestMessage(1L, 1L, "消息1"), createTestMessage(2L, 1L, "消息2"));
when(messageRepository.findByUserIdOrderByCreateTimeDesc(1L)).thenReturn(Flux.fromIterable(messages));
Flux<SysUserMessage> result = messageService.getMessagesByUser(1L);
StepVerifier.create(result)
.expectNextCount(2)
.verifyComplete();
}
@Test
void getMessagesByUser_shouldReturnEmptyWhenNone() {
when(messageRepository.findByUserIdOrderByCreateTimeDesc(999L)).thenReturn(Flux.empty());
Flux<SysUserMessage> result = messageService.getMessagesByUser(999L);
StepVerifier.create(result)
.verifyComplete();
}
// ==================== getUnreadCount ====================
@Test
void getUnreadCount_shouldReturnCount() {
when(messageRepository.countByUserIdAndIsRead(1L, "0")).thenReturn(Mono.just(5L));
Mono<Long> result = messageService.getUnreadCount(1L);
StepVerifier.create(result)
.expectNext(5L)
.verifyComplete();
}
@Test
void getUnreadCount_shouldReturnZero() {
when(messageRepository.countByUserIdAndIsRead(1L, "0")).thenReturn(Mono.just(0L));
Mono<Long> result = messageService.getUnreadCount(1L);
StepVerifier.create(result)
.expectNext(0L)
.verifyComplete();
}
// ==================== getUnreadMessages ====================
@Test
void getUnreadMessages_shouldReturnUnreadOnly() {
when(messageRepository.findByUserIdAndIsReadOrderByCreateTimeDesc(1L, "0"))
.thenReturn(Flux.just(createTestMessage(1L, 1L, "未读消息")));
Flux<SysUserMessage> result = messageService.getUnreadMessages(1L);
StepVerifier.create(result)
.expectNextCount(1)
.verifyComplete();
}
// ==================== createMessage ====================
@Test
void createMessage_shouldSaveAndReturn() {
SysUserMessage message = createTestMessage(null, 1L, "新消息");
when(messageRepository.save(any(SysUserMessage.class)))
.thenAnswer(invocation -> Mono.just(invocation.getArgument(0)));
Mono<SysUserMessage> result = messageService.createMessage(message);
StepVerifier.create(result)
.expectNextMatches(m -> m.getTitle().equals("新消息"))
.verifyComplete();
verify(messageRepository).save(message);
}
// ==================== markAsRead ====================
@Test
void markAsRead_shouldUpdateAndReturnMessage() {
SysUserMessage existing = createTestMessage(1L, 1L, "消息");
when(messageRepository.findById(1L)).thenReturn(Mono.just(existing));
when(messageRepository.save(any(SysUserMessage.class))).thenReturn(Mono.just(existing));
Mono<SysUserMessage> result = messageService.markAsRead(1L);
StepVerifier.create(result)
.expectNextMatches(m -> m.getIsRead().equals("1"))
.verifyComplete();
verify(messageRepository).save(existing);
assertThat(existing.getIsRead()).isEqualTo("1");
}
@Test
void markAsRead_shouldReturnEmptyWhenNotFound() {
when(messageRepository.findById(999L)).thenReturn(Mono.empty());
Mono<SysUserMessage> result = messageService.markAsRead(999L);
StepVerifier.create(result)
.verifyComplete();
verify(messageRepository, never()).save(any());
}
// ==================== markAllAsRead ====================
@Test
void markAllAsRead_shouldReturnCount() {
when(messageRepository.markAllAsReadByUserId(1L)).thenReturn(Mono.just(2L));
Mono<Long> result = messageService.markAllAsRead(1L);
StepVerifier.create(result)
.expectNext(2L)
.verifyComplete();
verify(messageRepository).markAllAsReadByUserId(1L);
}
@Test
void markAllAsRead_shouldReturnZeroWhenNoUnread() {
when(messageRepository.markAllAsReadByUserId(1L)).thenReturn(Mono.just(0L));
Mono<Long> result = messageService.markAllAsRead(1L);
StepVerifier.create(result)
.expectNext(0L)
.verifyComplete();
}
// ==================== deleteMessage ====================
@Test
void deleteMessage_shouldDelete() {
when(messageRepository.deleteById(1L)).thenReturn(Mono.empty());
Mono<Void> result = messageService.deleteMessage(1L);
StepVerifier.create(result)
.verifyComplete();
verify(messageRepository).deleteById(1L);
}
// ==================== helper ====================
private SysUserMessage createTestMessage(Long id, Long userId, String title) {
SysUserMessage message = new SysUserMessage();
message.setId(id);
message.setUserId(userId);
message.setTitle(title);
message.setContent("测试内容");
message.setIsRead("0");
message.setCreateTime(LocalDateTime.now());
return message;
}
}
@@ -0,0 +1,219 @@
package cn.novalon.gym.manage.notify.handler;
import cn.novalon.gym.manage.notify.core.domain.Banner;
import cn.novalon.gym.manage.notify.core.service.IBannerService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class BannerHandlerTest {
@Mock
private IBannerService bannerService;
private BannerHandler bannerHandler;
@BeforeEach
void setUp() {
bannerHandler = new BannerHandler(bannerService);
}
// ==================== getAllBanners ====================
@Test
void getAllBanners_shouldReturnOkWithBanners() {
List<Banner> banners = List.of(createTestBanner(1L, "轮播图1"), createTestBanner(2L, "轮播图2"));
when(bannerService.getAllBanners()).thenReturn(Flux.fromIterable(banners));
MockServerRequest request = MockServerRequest.builder().build();
Mono<ServerResponse> result = bannerHandler.getAllBanners(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void getAllBanners_shouldReturnOkWhenEmpty() {
when(bannerService.getAllBanners()).thenReturn(Flux.empty());
MockServerRequest request = MockServerRequest.builder().build();
Mono<ServerResponse> result = bannerHandler.getAllBanners(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== getActiveBanners ====================
@Test
void getActiveBanners_shouldReturnOkWithActiveBanners() {
when(bannerService.getActiveBanners()).thenReturn(Flux.just(createTestBanner(1L, "活跃轮播图")));
MockServerRequest request = MockServerRequest.builder().build();
Mono<ServerResponse> result = bannerHandler.getActiveBanners(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== getBannerById ====================
@Test
void getBannerById_shouldReturnOkWhenFound() {
when(bannerService.getBannerById(1L)).thenReturn(Mono.just(createTestBanner(1L, "轮播图1")));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "1")
.build();
Mono<ServerResponse> result = bannerHandler.getBannerById(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void getBannerById_shouldReturnNotFound() {
when(bannerService.getBannerById(999L)).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "999")
.build();
Mono<ServerResponse> result = bannerHandler.getBannerById(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
.verifyComplete();
}
// ==================== createBanner ====================
@Test
void createBanner_shouldReturnOkWhenCreated() {
Map<String, Object> body = Map.of(
"imageUrl", "https://example.com/banner.jpg",
"title", "新轮播图",
"subtitle", "副标题",
"sortOrder", 1,
"isActive", true
);
when(bannerService.createBanner(any(Banner.class))).thenReturn(Mono.just(createTestBanner(1L, "新轮播图")));
MockServerRequest request = MockServerRequest.builder()
.body(Mono.just(body));
Mono<ServerResponse> result = bannerHandler.createBanner(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== updateBanner ====================
@Test
void updateBanner_shouldReturnOkWhenUpdated() {
Map<String, Object> body = Map.of("title", "更新标题");
when(bannerService.updateBanner(eq(1L), any(Banner.class))).thenReturn(Mono.just(createTestBanner(1L, "更新标题")));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "1")
.body(Mono.just(body));
Mono<ServerResponse> result = bannerHandler.updateBanner(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void updateBanner_shouldReturnNotFound() {
Map<String, Object> body = Map.of("title", "更新标题");
when(bannerService.updateBanner(eq(999L), any(Banner.class))).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "999")
.body(Mono.just(body));
Mono<ServerResponse> result = bannerHandler.updateBanner(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
.verifyComplete();
}
// ==================== deleteBanner ====================
@Test
void deleteBanner_shouldReturnNoContent() {
Banner banner = createTestBanner(1L, "轮播图1");
banner.setDeletedAt(null);
when(bannerService.getBannerById(1L)).thenReturn(Mono.just(banner));
when(bannerService.deleteBanner(1L)).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "1")
.build();
Mono<ServerResponse> result = bannerHandler.deleteBanner(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NO_CONTENT))
.verifyComplete();
}
@Test
void deleteBanner_shouldReturnNotFound() {
when(bannerService.getBannerById(999L)).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "999")
.build();
Mono<ServerResponse> result = bannerHandler.deleteBanner(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
.verifyComplete();
}
// ==================== helper ====================
private Banner createTestBanner(Long id, String title) {
Banner banner = new Banner();
banner.setId(id);
banner.setImageUrl("https://example.com/banner-" + id + ".jpg");
banner.setTitle(title);
banner.setSubtitle("副标题");
banner.setSortOrder(id.intValue());
banner.setIsActive("1");
banner.setCreatedAt(LocalDateTime.now());
return banner;
}
}
@@ -0,0 +1,228 @@
package cn.novalon.gym.manage.notify.handler;
import cn.novalon.gym.manage.notify.core.domain.SysUserMessage;
import cn.novalon.gym.manage.notify.core.service.ISysUserMessageService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class SysUserMessageHandlerTest {
@Mock
private ISysUserMessageService messageService;
private SysUserMessageHandler handler;
@BeforeEach
void setUp() {
handler = new SysUserMessageHandler(messageService);
}
// ==================== getMessagesByUser ====================
@Test
void getMessagesByUser_shouldReturnOkWithMessages() {
List<SysUserMessage> messages = List.of(createTestMessage(1L, "消息1"), createTestMessage(2L, "消息2"));
when(messageService.getMessagesByUser(anyLong())).thenReturn(Flux.fromIterable(messages));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "1")
.build();
Mono<ServerResponse> result = handler.getMessagesByUser(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void getMessagesByUser_shouldReturnEmptyListWhenNone() {
when(messageService.getMessagesByUser(anyLong())).thenReturn(Flux.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "999")
.build();
Mono<ServerResponse> result = handler.getMessagesByUser(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== getUnreadCount ====================
@Test
void getUnreadCount_shouldReturnOkWithCount() {
when(messageService.getUnreadCount(anyLong())).thenReturn(Mono.just(5L));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "1")
.build();
Mono<ServerResponse> result = handler.getUnreadCount(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void getUnreadCount_shouldReturnZero() {
when(messageService.getUnreadCount(anyLong())).thenReturn(Mono.just(0L));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "1")
.build();
Mono<ServerResponse> result = handler.getUnreadCount(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== getUnreadList ====================
@Test
void getUnreadList_shouldReturnOk() {
when(messageService.getUnreadMessages(anyLong())).thenReturn(Flux.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "1")
.build();
Mono<ServerResponse> result = handler.getUnreadList(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== createMessage ====================
@Test
void createMessage_shouldReturnCreated() {
SysUserMessage message = createTestMessage(1L, "新消息");
when(messageService.createMessage(any(SysUserMessage.class))).thenReturn(Mono.just(message));
MockServerRequest request = MockServerRequest.builder()
.body(Mono.just(message));
Mono<ServerResponse> result = handler.createMessage(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== markAsRead ====================
@Test
void markAsRead_shouldReturnOk() {
SysUserMessage message = createTestMessage(1L, "消息");
when(messageService.markAsRead(anyLong())).thenReturn(Mono.just(message));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "1")
.build();
Mono<ServerResponse> result = handler.markAsRead(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void markAsRead_shouldReturnNotFound() {
when(messageService.markAsRead(anyLong())).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "999")
.build();
Mono<ServerResponse> result = handler.markAsRead(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.NOT_FOUND))
.verifyComplete();
}
// ==================== markAllAsRead ====================
@Test
void markAllAsRead_shouldReturnOk() {
when(messageService.markAllAsRead(anyLong())).thenReturn(Mono.just(3L));
MockServerRequest request = MockServerRequest.builder()
.pathVariable("userId", "1")
.build();
Mono<ServerResponse> result = handler.markAllAsRead(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== deleteMessage ====================
@Test
void deleteMessage_shouldReturnOk() {
when(messageService.deleteMessage(anyLong())).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "1")
.build();
Mono<ServerResponse> result = handler.deleteMessage(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
@Test
void deleteMessage_shouldReturnNotFound() {
when(messageService.deleteMessage(anyLong())).thenReturn(Mono.empty());
MockServerRequest request = MockServerRequest.builder()
.pathVariable("id", "999")
.build();
Mono<ServerResponse> result = handler.deleteMessage(request);
StepVerifier.create(result)
.assertNext(response -> assertThat(response.statusCode()).isEqualTo(HttpStatus.OK))
.verifyComplete();
}
// ==================== helper ====================
private SysUserMessage createTestMessage(Long id, String title) {
SysUserMessage message = new SysUserMessage();
message.setId(id);
message.setUserId(1L);
message.setTitle(title);
message.setContent("测试内容-" + id);
message.setIsRead("0");
return message;
}
}