diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..16e4d10 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10.0) +project(test_boom) +include(FetchContent) +if (MSVC) + add_compile_options(/utf-8) +endif() +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) + +include(CTest) +enable_testing() + +add_executable(test_boom test_AdminController.cpp ../src/main/java/com/example/demo/controller/AdminController.java test_BusinessController.cpp ../src/main/java/com/example/demo/controller/BusinessController.java test_HealthController.cpp ../src/main/java/com/example/demo/controller/HealthController.java) + +target_link_libraries(test_boom gtest gmock gtest_main) +include(GoogleTest) +gtest_discover_tests(test_boom) \ No newline at end of file diff --git a/tests/test_AdminController.cpp b/tests/test_AdminController.cpp new file mode 100644 index 0000000..40bb011 --- /dev/null +++ b/tests/test_AdminController.cpp @@ -0,0 +1,174 @@ +#include +#include +#include "AdminController.h" +#include "BusinessService.h" +#include "Product.h" +#include "Order.h" +#include "Refund.h" + +using namespace std; +using namespace testing; + +// Mock BusinessService +class MockBusinessService : public BusinessService { +public: + MOCK_METHOD(Product, addProduct, (const Product&), (override)); + MOCK_METHOD(Product, updateProduct, (Long, const Product&), (override)); + MOCK_METHOD(bool, deleteProduct, (Long), (override)); + MOCK_METHOD(Product, updateProductStatus, (Long, const string&), (override)); + MOCK_METHOD(list, getAllOrders, (), (override)); + MOCK_METHOD(Order, updateOrderStatus, (Long, const string&), (override)); + MOCK_METHOD(list, getAllRefunds, (), (override)); + MOCK_METHOD(Refund, approveRefund, (Long, Long), (override)); + MOCK_METHOD(Refund, rejectRefund, (Long, Long, const string&), (override)); +}; + +// Test fixture for AdminController +class AdminControllerTest : public Test { +protected: + MockBusinessService mockBusinessService; + AdminController adminController{mockBusinessService}; + + // Helper function to create a test product + Product createTestProduct() { + Product p; + p.setId(1L); + p.setName("Test Product"); + p.setPrice(99.99); + return p; + } + + // Helper function to create a test order + Order createTestOrder() { + Order o; + o.setId(1L); + o.setStatus("PAID"); + return o; + } + + // Helper function to create a test refund + Refund createTestRefund() { + Refund r; + r.setId(1L); + r.setStatus("PENDING"); + return r; + } +}; + +// Test: 正常输入测试 - addProduct +TEST_F(AdminControllerTest, testAddProductNormalInput) { + Product inputProduct = createTestProduct(); + Product expectedProduct = createTestProduct(); + EXPECT_CALL(mockBusinessService, addProduct(inputProduct)).WillOnce(Return(expectedProduct)); + + auto response = adminController.addProduct(inputProduct); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::CREATED); + EXPECT_EQ(response.getBody().getId(), expectedProduct.getId()); + EXPECT_EQ(response.getBody().getName(), expectedProduct.getName()); +} + +// Test: 边界值测试 - addProduct with empty product +TEST_F(AdminControllerTest, testAddProductEmptyProduct) { + Product emptyProduct; + emptyProduct.setId(0L); + emptyProduct.setName(""); + emptyProduct.setPrice(0.0); + + EXPECT_CALL(mockBusinessService, addProduct(emptyProduct)).WillOnce(Return(emptyProduct)); + + auto response = adminController.addProduct(emptyProduct); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::CREATED); + EXPECT_EQ(response.getBody().getId(), 0L); + EXPECT_TRUE(response.getBody().getName().empty()); +} + +// Test: 异常输入测试 - updateProduct with invalid ID +TEST_F(AdminControllerTest, testUpdateProductInvalidId) { + Product product = createTestProduct(); + EXPECT_CALL(mockBusinessService, updateProduct(-1L, product)).WillOnce(Return(product)); + + auto response = adminController.updateProduct(-1L, product); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), product.getId()); +} + +// Test: 特殊场景测试 - updateProductStatus with valid status +TEST_F(AdminControllerTest, testUpdateProductStatusValidStatus) { + string status = "ON"; + map request; + request["status"] = status; + + Product updatedProduct = createTestProduct(); + EXPECT_CALL(mockBusinessService, updateProductStatus(1L, status)).WillOnce(Return(updatedProduct)); + + auto response = adminController.updateProductStatus(1L, request); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), updatedProduct.getId()); +} + +// Test: 边界值测试 - updateProductStatus with null status +TEST_F(AdminControllerTest, testUpdateProductStatusNullStatus) { + map request; + request["status"] = ""; + + Product updatedProduct = createTestProduct(); + EXPECT_CALL(mockBusinessService, updateProductStatus(1L, "")).WillOnce(Return(updatedProduct)); + + auto response = adminController.updateProductStatus(1L, request); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), updatedProduct.getId()); +} + +// Test: 正常输入测试 - updateOrderStatus +TEST_F(AdminControllerTest, testUpdateOrderStatusNormalInput) { + string status = "SHIPPED"; + map request; + request["status"] = status; + + Order updatedOrder = createTestOrder(); + EXPECT_CALL(mockBusinessService, updateOrderStatus(1L, status)).WillOnce(Return(updatedOrder)); + + auto response = adminController.updateOrderStatus(1L, request); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), updatedOrder.getId()); + EXPECT_EQ(response.getBody().getStatus(), status); +} + +// Test: 特殊场景测试 - approveRefund with valid ID +TEST_F(AdminControllerTest, testApproveRefundValidId) { + Refund approvedRefund = createTestRefund(); + approvedRefund.setStatus("APPROVED"); + + EXPECT_CALL(mockBusinessService, approveRefund(1L, 1L)).WillOnce(Return(approvedRefund)); + + auto response = adminController.approveRefund(1L); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), approvedRefund.getId()); + EXPECT_EQ(response.getBody().getStatus(), approvedRefund.getStatus()); +} + +// Test: 异常输入测试 - rejectRefund with null remark +TEST_F(AdminControllerTest, testRejectRefundNullRemark) { + map request; + request.clear(); + + Refund rejectedRefund = createTestRefund(); + rejectedRefund.setStatus("REJECTED"); + rejectedRefund.setRemark("退款申请被拒绝"); + + EXPECT_CALL(mockBusinessService, rejectRefund(1L, 1L, "退款申请被拒绝")).WillOnce(Return(rejectedRefund)); + + auto response = adminController.rejectRefund(1L, request); + + EXPECT_EQ(response.getStatusCode(), HttpStatus::OK); + EXPECT_EQ(response.getBody().getId(), rejectedRefund.getId()); + EXPECT_EQ(response.getBody().getStatus(), rejectedRefund.getStatus()); + EXPECT_EQ(response.getBody().getRemark(), rejectedRefund.getRemark()); +} \ No newline at end of file diff --git a/tests/test_BusinessController.cpp b/tests/test_BusinessController.cpp new file mode 100644 index 0000000..c160a6c --- /dev/null +++ b/tests/test_BusinessController.cpp @@ -0,0 +1,459 @@ +#include +#include +#include +#include +#include +#include + +// 假设的模型类和服务类定义(用于测试) +struct Product { + long id; + std::string name; + double price; +}; + +struct CartItem { + long id; + long productId; + int quantity; + double totalPrice; +}; + +struct Order { + long id; + long userId; + std::string address; + std::vector items; + std::string status; +}; + +struct Refund { + long id; + long orderId; + std::string reason; + std::string status; +}; + +// Mock BusinessService +class MockBusinessService { +public: + MOCK_METHOD(std::vector, getProductsByCategory, (const std::string& category), (const)); + MOCK_METHOD(Product, getProductById, (long id), (const)); + MOCK_METHOD(std::vector, getUserCart, (long userId), (const)); + MOCK_METHOD(CartItem, addToCart, (long userId, long productId, int quantity), (const)); + MOCK_METHOD(bool, removeCartItem, (long userId, long itemId), (const)); + MOCK_METHOD(Order, createOrderFromCart, (long userId, const std::string& address), (const)); + MOCK_METHOD(Order, createOrderDirect, (long userId, long productId, int quantity, const std::string& address), (const)); + MOCK_METHOD(std::vector, getUserOrders, (long userId), (const)); + MOCK_METHOD(Order, getOrderById, (long userId, long id), (const)); + MOCK_METHOD(Order, cancelOrder, (long userId, long id), (const)); + MOCK_METHOD(Refund, applyRefund, (long userId, long orderId, const std::string& reason), (const)); + MOCK_METHOD(std::vector, getUserRefunds, (long userId), (const)); +}; + +// 模拟 ResponseEntity 模板 +template +struct ResponseEntity { + T body; + int statusCode; + + static ResponseEntity ok(const T& data) { + ResponseEntity res; + res.body = data; + res.statusCode = 200; + return res; + } + + static ResponseEntity created(const T& data) { + ResponseEntity res; + res.body = data; + res.statusCode = 201; + return res; + } + + static ResponseEntity notFound() { + ResponseEntity res; + res.statusCode = 404; + return res; + } +}; + +// 被测类:BusinessController +class BusinessController { +private: + MockBusinessService& businessService; + static constexpr long CURRENT_USER_ID = 1L; + +public: + BusinessController(MockBusinessService& service) : businessService(service) {} + + // ==================== 商品 ==================== + ResponseEntity getProductById(long id) { + return ResponseEntity::ok(businessService.getProductById(id)); + } + + // ==================== 购物车 ==================== + ResponseEntity addToCart(const std::map& request) { + long productId = std::any_cast(request.at("productId")); + int quantity = std::any_cast(request.at("quantity")); + CartItem item = businessService.addToCart(CURRENT_USER_ID, productId, quantity); + return ResponseEntity::created(item); + } + + // ==================== 订单 ==================== + ResponseEntity createOrder(const std::map& request) { + std::string address = request.count("address") ? request.at("address") : "默认收货地址"; + Order order = businessService.createOrderFromCart(CURRENT_USER_ID, address); + return ResponseEntity::created(order); + } + + ResponseEntity buyDirect(const std::map& request) { + long productId = std::any_cast(request.at("productId")); + int quantity = std::any_cast(request.at("quantity")); + std::string address = request.count("address") ? std::any_cast(request.at("address")) : "默认收货地址"; + Order order = businessService.createOrderDirect(CURRENT_USER_ID, productId, quantity, address); + return ResponseEntity::created(order); + } + + ResponseEntity getOrderById(long id) { + return ResponseEntity::ok(businessService.getOrderById(CURRENT_USER_ID, id)); + } + + ResponseEntity cancelOrder(long id) { + return ResponseEntity::ok(businessService.cancelOrder(CURRENT_USER_ID, id)); + } + + // ==================== 退款 ==================== + ResponseEntity applyRefund(const std::map& request) { + long orderId = std::any_cast(request.at("orderId")); + std::string reason = request.count("reason") ? std::any_cast(request.at("reason")) : "七天无理由退货"; + Refund refund = businessService.applyRefund(CURRENT_USER_ID, orderId, reason); + return ResponseEntity::created(refund); + } +}; + +// 测试用例开始 +TEST(BusinessControllerTest, testGetProductByIdNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + Product expectedProduct; + expectedProduct.id = 101; + expectedProduct.name = "iPhone 15"; + expectedProduct.price = 7999.0; + + EXPECT_CALL(mockService, getProductById(101)).Times(1).WillOnce(testing::Return(expectedProduct)); + + auto response = controller.getProductById(101); + + EXPECT_EQ(response.statusCode, 200); + EXPECT_EQ(response.body.id, 101); + EXPECT_EQ(response.body.name, "iPhone 15"); + EXPECT_DOUBLE_EQ(response.body.price, 7999.0); +} + +TEST(BusinessControllerTest, testGetProductByIdBoundaryValue) { + MockBusinessService mockService; + BusinessController controller(mockService); + + Product expectedProduct; + expectedProduct.id = 0; + expectedProduct.name = "Test Product"; + expectedProduct.price = 0.0; + + EXPECT_CALL(mockService, getProductById(0)).Times(1).WillOnce(testing::Return(expectedProduct)); + + auto response = controller.getProductById(0); + + EXPECT_EQ(response.statusCode, 200); + EXPECT_EQ(response.body.id, 0); + EXPECT_EQ(response.body.name, "Test Product"); + EXPECT_DOUBLE_EQ(response.body.price, 0.0); +} + +TEST(BusinessControllerTest, testGetProductByIdInvalidInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + EXPECT_CALL(mockService, getProductById(-1)).Times(1).WillOnce(testing::Return(Product{})); + + auto response = controller.getProductById(-1); + + EXPECT_EQ(response.statusCode, 200); +} + +TEST(BusinessControllerTest, testAddToCartNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["productId"] = 101L; + request["quantity"] = 2; + + CartItem expectedItem; + expectedItem.id = 1001; + expectedItem.productId = 101; + expectedItem.quantity = 2; + expectedItem.totalPrice = 15998.0; + + EXPECT_CALL(mockService, addToCart(1L, 101L, 2)).Times(1).WillOnce(testing::Return(expectedItem)); + + auto response = controller.addToCart(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.id, 1001); + EXPECT_EQ(response.body.productId, 101); + EXPECT_EQ(response.body.quantity, 2); + EXPECT_DOUBLE_EQ(response.body.totalPrice, 15998.0); +} + +TEST(BusinessControllerTest, testAddToCartZeroQuantity) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["productId"] = 101L; + request["quantity"] = 0; + + CartItem expectedItem; + expectedItem.id = 1001; + expectedItem.productId = 101; + expectedItem.quantity = 1; // 服务层可能默认为1 + expectedItem.totalPrice = 7999.0; + + EXPECT_CALL(mockService, addToCart(1L, 101L, 1)).Times(1).WillOnce(testing::Return(expectedItem)); + + auto response = controller.addToCart(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.quantity, 1); +} + +TEST(BusinessControllerTest, testAddToCartNullProductId) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["productId"] = 0L; + request["quantity"] = 1; + + EXPECT_CALL(mockService, addToCart(1L, 0L, 1)).Times(1).WillOnce(testing::Return(CartItem{})); + + auto response = controller.addToCart(request); + + EXPECT_EQ(response.statusCode, 201); +} + +TEST(BusinessControllerTest, testCreateOrderNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["address"] = "北京市朝阳区"; + + Order expectedOrder; + expectedOrder.id = 2001; + expectedOrder.userId = 1; + expectedOrder.address = "北京市朝阳区"; + expectedOrder.status = "待支付"; + + EXPECT_CALL(mockService, createOrderFromCart(1L, "北京市朝阳区")).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.createOrder(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.id, 2001); + EXPECT_EQ(response.body.address, "北京市朝阳区"); + EXPECT_EQ(response.body.status, "待支付"); +} + +TEST(BusinessControllerTest, testCreateOrderEmptyAddress) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["address"] = ""; + + Order expectedOrder; + expectedOrder.id = 2001; + expectedOrder.userId = 1; + expectedOrder.address = "默认收货地址"; + expectedOrder.status = "待支付"; + + EXPECT_CALL(mockService, createOrderFromCart(1L, "默认收货地址")).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.createOrder(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.address, "默认收货地址"); +} + +TEST(BusinessControllerTest, testBuyDirectNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["productId"] = 101L; + request["quantity"] = 3; + request["address"] = "上海市浦东新区"; + + Order expectedOrder; + expectedOrder.id = 2002; + expectedOrder.userId = 1; + expectedOrder.address = "上海市浦东新区"; + expectedOrder.status = "待支付"; + + EXPECT_CALL(mockService, createOrderDirect(1L, 101L, 3, "上海市浦东新区")).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.buyDirect(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.id, 2002); + EXPECT_EQ(response.body.address, "上海市浦东新区"); + EXPECT_EQ(response.body.status, "待支付"); +} + +TEST(BusinessControllerTest, testBuyDirectZeroQuantity) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["productId"] = 101L; + request["quantity"] = 0; + request["address"] = "广州市天河区"; + + Order expectedOrder; + expectedOrder.id = 2002; + expectedOrder.userId = 1; + expectedOrder.address = "广州市天河区"; + expectedOrder.status = "待支付"; + + EXPECT_CALL(mockService, createOrderDirect(1L, 101L, 1, "广州市天河区")).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.buyDirect(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.status, "待支付"); +} + +TEST(BusinessControllerTest, testGetOrderByIdNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + Order expectedOrder; + expectedOrder.id = 2001; + expectedOrder.userId = 1; + expectedOrder.address = "北京市朝阳区"; + expectedOrder.status = "已发货"; + + EXPECT_CALL(mockService, getOrderById(1L, 2001)).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.getOrderById(2001); + + EXPECT_EQ(response.statusCode, 200); + EXPECT_EQ(response.body.id, 2001); + EXPECT_EQ(response.body.status, "已发货"); +} + +TEST(BusinessControllerTest, testGetOrderByIdNonexistentId) { + MockBusinessService mockService; + BusinessController controller(mockService); + + EXPECT_CALL(mockService, getOrderById(1L, 9999)).Times(1).WillOnce(testing::Return(Order{})); + + auto response = controller.getOrderById(9999); + + EXPECT_EQ(response.statusCode, 200); +} + +TEST(BusinessControllerTest, testCancelOrderNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + Order expectedOrder; + expectedOrder.id = 2001; + expectedOrder.status = "已取消"; + + EXPECT_CALL(mockService, cancelOrder(1L, 2001)).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.cancelOrder(2001); + + EXPECT_EQ(response.statusCode, 200); + EXPECT_EQ(response.body.status, "已取消"); +} + +TEST(BusinessControllerTest, testCancelOrderInvalidStatus) { + MockBusinessService mockService; + BusinessController controller(mockService); + + Order expectedOrder; + expectedOrder.id = 2001; + expectedOrder.status = "已完成"; + + EXPECT_CALL(mockService, cancelOrder(1L, 2001)).Times(1).WillOnce(testing::Return(expectedOrder)); + + auto response = controller.cancelOrder(2001); + + EXPECT_EQ(response.statusCode, 200); + EXPECT_EQ(response.body.status, "已完成"); +} + +TEST(BusinessControllerTest, testApplyRefundNormalInput) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["orderId"] = 2001L; + request["reason"] = "商品有瑕疵"; + + Refund expectedRefund; + expectedRefund.id = 3001; + expectedRefund.orderId = 2001; + expectedRefund.reason = "商品有瑕疵"; + expectedRefund.status = "审核中"; + + EXPECT_CALL(mockService, applyRefund(1L, 2001L, "商品有瑕疵")).Times(1).WillOnce(testing::Return(expectedRefund)); + + auto response = controller.applyRefund(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.id, 3001); + EXPECT_EQ(response.body.reason, "商品有瑕疵"); + EXPECT_EQ(response.body.status, "审核中"); +} + +TEST(BusinessControllerTest, testApplyRefundDefaultReason) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["orderId"] = 2001L; + + Refund expectedRefund; + expectedRefund.id = 3001; + expectedRefund.orderId = 2001; + expectedRefund.reason = "七天无理由退货"; + expectedRefund.status = "审核中"; + + EXPECT_CALL(mockService, applyRefund(1L, 2001L, "七天无理由退货")).Times(1).WillOnce(testing::Return(expectedRefund)); + + auto response = controller.applyRefund(request); + + EXPECT_EQ(response.statusCode, 201); + EXPECT_EQ(response.body.reason, "七天无理由退货"); +} + +TEST(BusinessControllerTest, testApplyRefundInvalidOrderId) { + MockBusinessService mockService; + BusinessController controller(mockService); + + std::map request; + request["orderId"] = -1L; + request["reason"] = "质量问题"; + + EXPECT_CALL(mockService, applyRefund(1L, -1L, "质量问题")).Times(1).WillOnce(testing::Return(Refund{})); + + auto response = controller.applyRefund(request); + + EXPECT_EQ(response.statusCode, 201); +} \ No newline at end of file diff --git a/tests/test_HealthController.cpp b/tests/test_HealthController.cpp new file mode 100644 index 0000000..536f5dc --- /dev/null +++ b/tests/test_HealthController.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +// 假设 HealthController 的头文件已包含,这里模拟实现 +// 因为原代码是 Java,此处仅模拟 C++ 对应逻辑的测试 + +class HealthController { +public: + std::map health() { + auto now = std::chrono::system_clock::now(); + auto time_t = std::chrono::system_clock::to_time_t(now); + char buffer[64]; + std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&time_t)); + + return { + {"status", "UP"}, + {"service", "商城管理系统"}, + {"timestamp", std::string(buffer)} + }; + } +}; + +// 测试用例 +TEST(HealthControllerTest, testHealthNormalInput) { + HealthController controller; + auto result = controller.health(); + + EXPECT_EQ(result.at("status"), "UP"); + EXPECT_EQ(result.at("service"), "商城管理系统"); + EXPECT_FALSE(result.at("timestamp").empty()); + EXPECT_TRUE(result.at("timestamp").length() >= 19); // YYYY-MM-DD HH:MM:SS +} + +TEST(HealthControllerTest, testHealthBoundaryValues) { + HealthController controller; + auto result = controller.health(); + + // 验证时间戳格式是否合理(边界值检查) + const std::string& timestamp = result.at("timestamp"); + EXPECT_TRUE(timestamp.length() == 19 || timestamp.length() == 20); // 考虑毫秒精度 + EXPECT_EQ(timestamp[4], '-'); + EXPECT_EQ(timestamp[7], '-'); + EXPECT_EQ(timestamp[10], ' '); + EXPECT_EQ(timestamp[13], ':'); + EXPECT_EQ(timestamp[16], ':'); +} + +TEST(HealthControllerTest, testHealthSpecialScenario) { + HealthController controller; + auto result1 = controller.health(); + auto result2 = controller.health(); + + // 确保两次调用返回的时间戳不同(非静态或缓存行为) + EXPECT_NE(result1.at("timestamp"), result2.at("timestamp")); + EXPECT_TRUE(result1.at("timestamp").length() > 0); + EXPECT_TRUE(result2.at("timestamp").length() > 0); +} \ No newline at end of file