增加 后端,后台管理系统,uniapp会员端的自动化测试。
This commit is contained in:
@@ -100,6 +100,11 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
package cn.novalon.gym.manage.datacount.handler;
|
||||
|
||||
import cn.novalon.gym.manage.datacount.domain.*;
|
||||
import cn.novalon.gym.manage.datacount.service.IDataStatisticsService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
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 static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 数据统计 Handler 单元测试
|
||||
*/
|
||||
class DataStatisticsHandlerTest {
|
||||
|
||||
@Mock
|
||||
private IDataStatisticsService dataStatisticsService;
|
||||
|
||||
private DataStatisticsHandler handler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
handler = new DataStatisticsHandler();
|
||||
// 通过反射注入 mock
|
||||
try {
|
||||
var field = DataStatisticsHandler.class.getDeclaredField("dataStatisticsService");
|
||||
field.setAccessible(true);
|
||||
field.set(handler, dataStatisticsService);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("综合统计 - 正常返回")
|
||||
void testGetStatisticsSummary() {
|
||||
StatisticsSummary summary = StatisticsSummary.builder()
|
||||
.statDate("2026-07-21")
|
||||
.memberStatistics(MemberStatistics.builder()
|
||||
.newMembers(10L).totalMembers(500L).build())
|
||||
.bookingStatistics(BookingStatistics.builder()
|
||||
.newBookings(25L).attendanceRate(92.5).build())
|
||||
.signInStatistics(SignInStatistics.builder()
|
||||
.totalSignIns(80L).successRate(95.0).build())
|
||||
.build();
|
||||
|
||||
when(dataStatisticsService.getStatisticsSummaryWithCache(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.just(summary));
|
||||
|
||||
Mono<ServerResponse> result = handler.getStatisticsSummary(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("综合统计 - 异常降级返回空结果")
|
||||
void testGetStatisticsSummaryErrorFallback() {
|
||||
when(dataStatisticsService.getStatisticsSummaryWithCache(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("数据库连接失败")));
|
||||
|
||||
Mono<ServerResponse> result = handler.getStatisticsSummary(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> {
|
||||
return response.statusCode().is2xxSuccessful();
|
||||
})
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("会员统计 - 正常返回")
|
||||
void testGetMemberStatistics() {
|
||||
MemberStatistics stats = MemberStatistics.builder()
|
||||
.statDate("2026-07-21")
|
||||
.newMembers(15L)
|
||||
.activeMembers(120L)
|
||||
.totalMembers(500L)
|
||||
.signInMembers(80L)
|
||||
.bookingMembers(60L)
|
||||
.cancelBookingMembers(5L)
|
||||
.build();
|
||||
|
||||
when(dataStatisticsService.getMemberStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.just(stats));
|
||||
|
||||
Mono<ServerResponse> result = handler.getMemberStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("预约统计 - 正常返回含出席率和取消率")
|
||||
void testGetBookingStatistics() {
|
||||
BookingStatistics stats = BookingStatistics.builder()
|
||||
.statDate("2026-07-21")
|
||||
.newBookings(30L)
|
||||
.cancelBookings(3L)
|
||||
.attendBookings(26L)
|
||||
.absentBookings(1L)
|
||||
.attendanceRate(96.3)
|
||||
.cancelRate(10.0)
|
||||
.bookingMembers(28L)
|
||||
.cancelMembers(3L)
|
||||
.build();
|
||||
|
||||
when(dataStatisticsService.getBookingStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.just(stats));
|
||||
|
||||
Mono<ServerResponse> result = handler.getBookingStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("签到统计 - 正常返回含细分类型")
|
||||
void testGetSignInStatistics() {
|
||||
SignInStatistics stats = SignInStatistics.builder()
|
||||
.statDate("2026-07-21")
|
||||
.totalSignIns(100L)
|
||||
.successSignIns(95L)
|
||||
.failedSignIns(5L)
|
||||
.successRate(95.0)
|
||||
.signInMembers(80L)
|
||||
.qrCodeSignIns(60L)
|
||||
.manualSignIns(20L)
|
||||
.faceSignIns(15L)
|
||||
.build();
|
||||
|
||||
when(dataStatisticsService.getSignInStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.just(stats));
|
||||
|
||||
Mono<ServerResponse> result = handler.getSignInStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("历史统计 - 返回统计列表")
|
||||
void testQueryHistoricalStatistics() {
|
||||
DataStatistics ds1 = new DataStatistics();
|
||||
ds1.setStatType("MEMBER");
|
||||
ds1.setCount(100L);
|
||||
|
||||
when(dataStatisticsService.queryHistoricalStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Flux.just(ds1));
|
||||
|
||||
Mono<ServerResponse> result = handler.queryHistoricalStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("导出统计 - 返回Excel字节数组")
|
||||
void testExportStatistics() {
|
||||
byte[] excelBytes = new byte[]{0x50, 0x4B, 0x03, 0x04}; // ZIP magic bytes (xlsx)
|
||||
when(dataStatisticsService.exportStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.just(excelBytes));
|
||||
|
||||
Mono<ServerResponse> result = handler.exportStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("导出统计 - 异常降级返回错误消息")
|
||||
void testExportStatisticsError() {
|
||||
when(dataStatisticsService.exportStatistics(any(StatisticsQuery.class)))
|
||||
.thenReturn(Mono.error(new RuntimeException("导出失败")));
|
||||
|
||||
Mono<ServerResponse> result = handler.exportStatistics(
|
||||
MockServerRequest.builder().build());
|
||||
|
||||
StepVerifier.create(result)
|
||||
.expectNextMatches(response -> response.statusCode().is2xxSuccessful())
|
||||
.verifyComplete();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user