CollisionAvoidance/tests/TrafficLightDetectorTest.cpp

145 lines
5.4 KiB
C++

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <fstream>
#include <nlohmann/json.hpp>
#include "detector/TrafficLightDetector.h"
#include "config/IntersectionConfig.h"
#include "vehicle/ControllableVehicles.h"
#include "utils/Logger.h"
#include "types/VehicleCommand.h"
#include "types/TrafficLightTypes.h"
class MockControllableVehicles : public ControllableVehicles {
public:
explicit MockControllableVehicles() : ControllableVehicles("config/vehicle_speed_limits.json") {}
MOCK_METHOD(bool, isControllable, (const std::string& vehicleNo), (const, override));
MOCK_METHOD(void, sendCommand, (const std::string& vehicleNo, const VehicleCommand& command), (override));
};
class TrafficLightDetectorTest : public ::testing::Test {
protected:
void SetUp() override {
// 创建测试用的交叉口配置
Intersection intersection;
intersection.id = "INT001";
intersection.name = "Test Intersection";
intersection.position.latitude = 36.36;
intersection.position.longitude = 120.08;
intersection.radius = 50.0;
intersection.trafficLightId = "TL001";
// 创建临时配置文件
std::ofstream config_file("test_intersections.json");
nlohmann::json j;
j["intersections"] = nlohmann::json::array();
j["intersections"].push_back({
{"id", intersection.id},
{"name", intersection.name},
{"position", {
{"latitude", intersection.position.latitude},
{"longitude", intersection.position.longitude}
}},
{"radius", intersection.radius},
{"trafficLightId", intersection.trafficLightId}
});
config_file << j.dump(4);
config_file.close();
intersectionConfig = IntersectionConfig::load("test_intersections.json");
mockControllableVehicles = std::make_shared<::testing::NiceMock<MockControllableVehicles>>();
detector = std::make_unique<TrafficLightDetector>(intersectionConfig, *mockControllableVehicles);
}
void TearDown() override {
detector.reset();
std::remove("test_intersections.json");
}
// 创建测试用的红绿灯信号
TrafficLightSignal createTestSignal(const std::string& id, SignalStatus status) {
TrafficLightSignal signal;
signal.trafficLightId = id;
signal.status = status;
signal.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
return signal;
}
// 创建测试用的车辆数据
Vehicle createTestVehicle(const std::string& id, double lat, double lon) {
Vehicle v;
v.id = id;
v.vehicleNo = id;
v.geo.latitude = lat;
v.geo.longitude = lon;
v.timestamp = std::chrono::system_clock::now().time_since_epoch().count();
return v;
}
std::unique_ptr<TrafficLightDetector> detector;
IntersectionConfig intersectionConfig;
std::shared_ptr<MockControllableVehicles> mockControllableVehicles;
};
// 测试红绿灯信号处理
TEST_F(TrafficLightDetectorTest, SignalProcessing) {
// 创建一个在交叉口范围内的车辆
Vehicle vehicle = createTestVehicle("V001", 36.36, 120.08);
std::vector<Vehicle> vehicles = {vehicle};
// 测试红灯
TrafficLightSignal redSignal = createTestSignal("TL001", SignalStatus::RED);
EXPECT_CALL(*mockControllableVehicles, isControllable("V001"))
.WillOnce(::testing::Return(true));
EXPECT_CALL(*mockControllableVehicles, sendCommand("V001", ::testing::_))
.Times(1);
detector->processSignal(redSignal, vehicles);
// 测试绿灯
TrafficLightSignal greenSignal = createTestSignal("TL001", SignalStatus::GREEN);
EXPECT_CALL(*mockControllableVehicles, isControllable("V001"))
.WillOnce(::testing::Return(true));
EXPECT_CALL(*mockControllableVehicles, sendCommand("V001", ::testing::_))
.Times(1);
detector->processSignal(greenSignal, vehicles);
}
// 测试无效的红绿灯信号
TEST_F(TrafficLightDetectorTest, InvalidSignal) {
Vehicle vehicle = createTestVehicle("V001", 36.36, 120.08);
std::vector<Vehicle> vehicles = {vehicle};
// 测试无效的红绿灯ID
TrafficLightSignal invalidSignal = createTestSignal("TL999", SignalStatus::RED);
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
.Times(0);
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
.Times(0);
detector->processSignal(invalidSignal, vehicles);
}
// 测试边界情况
TEST_F(TrafficLightDetectorTest, EdgeCases) {
// 测试空车辆列表
std::vector<Vehicle> emptyVehicles;
TrafficLightSignal signal = createTestSignal("TL001", SignalStatus::RED);
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
.Times(0);
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
.Times(0);
detector->processSignal(signal, emptyVehicles);
// 测试交叉口范围外的车辆
Vehicle farVehicle = createTestVehicle("V002", 36.40, 120.12);
std::vector<Vehicle> vehicles = {farVehicle};
EXPECT_CALL(*mockControllableVehicles, isControllable(::testing::_))
.Times(0);
EXPECT_CALL(*mockControllableVehicles, sendCommand(::testing::_, ::testing::_))
.Times(0);
detector->processSignal(signal, vehicles);
}