using System; using System.Linq; using CncModels.Constants; using CncModels.Dto.Settings; using CncService; using CncService.Impl; using Xunit; namespace CncService.Tests { /// /// WorkshopService 车间管理测试 /// 测试场景:CRUD、唯一性校验、启停、删除约束、参数校验、边界值 /// [Collection("Database")] public class WorkshopServiceTests : IDisposable { private readonly WorkshopService _service; public WorkshopServiceTests() { TestDb.TruncateAll(); _service = ServiceFactory.CreateWorkshopService(); } public void Dispose() { TestDb.TruncateAll(); } // ======== GetList ======== [Fact] public void GetList_返回种子数据车间() { var list = _service.GetList(null); Assert.NotNull(list); Assert.True(list.Count >= 2, "种子数据至少有2个车间"); Assert.Contains(list, w => w.Name == "A栋"); Assert.Contains(list, w => w.Name == "B栋"); } [Fact] public void GetList_关键字搜索_只返回匹配项() { var list = _service.GetList("A"); Assert.NotNull(list); Assert.All(list, w => Assert.Contains("A", w.Name)); } [Fact] public void GetList_不存在的关键字_返回空列表() { var list = _service.GetList("不存在的车间"); Assert.Empty(list); } // ======== GetById ======== [Fact] public void GetById_存在的ID_返回车间实体() { var w = _service.GetById(1); Assert.NotNull(w); Assert.Equal("A栋", w.Name); Assert.Equal(1, w.SortOrder); Assert.Equal(1, w.IsEnabled); } [Fact] public void GetById_不存在的ID_抛出NotFound异常() { var ex = Assert.Throws(() => _service.GetById(99999)); Assert.Equal(ErrorCode.NotFound, ex.Code); } [Fact] public void GetById_ID为0_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.GetById(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void GetById_负数ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.GetById(-1)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== Create ======== [Fact] public void Create_正常新增_返回自增ID() { var id = _service.Create(new CreateWorkshopRequest { Name = "C栋", SortOrder = 3 }); Assert.True(id > 0); var created = _service.GetById(id); Assert.Equal("C栋", created.Name); Assert.Equal(3, created.SortOrder); Assert.Equal(1, created.IsEnabled); // 默认启用 } [Fact] public void Create_请求为null_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Create(null)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Create_名称为空_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Create(new CreateWorkshopRequest { Name = "", SortOrder = 1 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Create_名称为空格_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Create(new CreateWorkshopRequest { Name = " ", SortOrder = 1 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Create_重复名称_抛出Conflict异常() { var ex = Assert.Throws(() => _service.Create(new CreateWorkshopRequest { Name = "A栋", SortOrder = 3 })); Assert.Equal(ErrorCode.Conflict, ex.Code); } [Fact] public void Create_重复名称大小写不同_抛出Conflict异常() { var ex = Assert.Throws(() => _service.Create(new CreateWorkshopRequest { Name = "a栋", SortOrder = 3 })); Assert.Equal(ErrorCode.Conflict, ex.Code); } // ======== Update ======== [Fact] public void Update_正常修改_返回true() { var result = _service.Update(1, new UpdateWorkshopRequest { Name = "A栋-修改", SortOrder = 10 }); Assert.True(result); var updated = _service.GetById(1); Assert.Equal("A栋-修改", updated.Name); Assert.Equal(10, updated.SortOrder); } [Fact] public void Update_请求为null_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Update(1, null)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Update_不存在的ID_抛出NotFound异常() { var ex = Assert.Throws(() => _service.Update(99999, new UpdateWorkshopRequest { Name = "测试", SortOrder = 1 })); Assert.Equal(ErrorCode.NotFound, ex.Code); } [Fact] public void Update_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Update(0, new UpdateWorkshopRequest { Name = "测试", SortOrder = 1 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Update_Name为null_保留原名称() { var before = _service.GetById(1); _service.Update(1, new UpdateWorkshopRequest { Name = null, SortOrder = 5 }); var after = _service.GetById(1); Assert.Equal(before.Name, after.Name); Assert.Equal(5, after.SortOrder); } // ======== Delete ======== [Fact] public void Delete_空车间_返回true() { // 先新增一个空车间 var id = _service.Create(new CreateWorkshopRequest { Name = "待删除", SortOrder = 99 }); var result = _service.Delete(id); Assert.True(result); } [Fact] public void Delete_删除后查询不到() { var id = _service.Create(new CreateWorkshopRequest { Name = "临时车间", SortOrder = 99 }); _service.Delete(id); Assert.Throws(() => _service.GetById(id)); } [Fact] public void Delete_车间下有机床_抛出DataReferenced异常() { // 先插入有效的采集地址 TestDb.Execute(@"INSERT INTO cnc_collect_address (name, url, brand_id, collect_interval, is_enabled, created_at, updated_at) VALUES ('测试地址', 'http://test', 1, 30, 1, NOW(), NOW())"); TestDb.Execute(@"INSERT INTO cnc_machine (device_code, name, workshop_id, collect_address_id, ip_address, brand_id, is_enabled, is_online, created_at, updated_at) VALUES ('M001', '机床1', 1, 1, '0.0.0.0', 1, 1, 0, NOW(), NOW())"); var ex = Assert.Throws(() => _service.Delete(1)); Assert.Equal(ErrorCode.DataReferenced, ex.Code); } [Fact] public void Delete_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Delete(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== ToggleEnabled ======== [Fact] public void ToggleEnabled_切换启用状态() { var before = _service.GetById(1); var beforeState = before.IsEnabled; _service.ToggleEnabled(1); var after = _service.GetById(1); Assert.NotEqual(beforeState, after.IsEnabled); } [Fact] public void ToggleEnabled_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.ToggleEnabled(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== GetMachineCount ======== [Fact] public void GetMachineCount_无机床_返回0() { var count = _service.GetMachineCount(1); Assert.Equal(0, count); } [Fact] public void GetMachineCount_有机床_返回正确数量() { // 先插入一个有效的采集地址,满足cnc_machine的外键约束 TestDb.Execute(@"INSERT INTO cnc_collect_address (name, url, brand_id, collect_interval, is_enabled, created_at, updated_at) VALUES ('测试地址', 'http://test', 1, 30, 1, NOW(), NOW())"); TestDb.Execute(@"INSERT INTO cnc_machine (device_code, name, workshop_id, collect_address_id, ip_address, brand_id, is_enabled, is_online, created_at, updated_at) VALUES ('M001', '机床1', 1, 1, '0.0.0.0', 1, 1, 0, NOW(), NOW()), ('M002', '机床2', 1, 1, '0.0.0.0', 1, 1, 0, NOW(), NOW())"); var count = _service.GetMachineCount(1); Assert.Equal(2, count); } [Fact] public void GetMachineCount_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.GetMachineCount(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } } }