using System; using System.Linq; using CncModels.Constants; using CncModels.Dto; using CncModels.Dto.Machine; using CncService; using CncService.Impl; using Xunit; namespace CncService.Tests { /// /// MachineService 机床管理测试 /// 测试场景:CRUD、唯一性校验(设备编码)、删除解绑工人、参数校验、边界值 /// [Collection("Database")] public class MachineServiceTests : IDisposable { private readonly MachineService _service; public MachineServiceTests() { TestDb.TruncateAll(); _service = ServiceFactory.CreateMachineService(); } public void Dispose() { TestDb.TruncateAll(); } /// 辅助方法:插入一条机床用于测试(先创建有效的采集地址) private int InsertTestMachine(string deviceCode = "M001") { // 先插入有效的采集地址(满足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())"); return _service.Create(new CreateMachineRequest { DeviceCode = deviceCode, Name = "测试机床", WorkshopId = 1, CollectAddressId = 1, IpAddress = "192.168.1.1", BrandId = 1 }); } // ======== GetList ======== [Fact] public void GetList_无数据_返回空列表() { var result = _service.GetList(new MachineQuery { Page = 1, PageSize = 20 }); Assert.NotNull(result); Assert.Equal(0, result.Total); } [Fact] public void GetList_有数据_返回分页结果() { InsertTestMachine("M001"); InsertTestMachine("M002"); var result = _service.GetList(new MachineQuery { Page = 1, PageSize = 20 }); Assert.Equal(2, result.Total); } [Fact] public void GetList_查询参数为null_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.GetList(null)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== GetById ======== [Fact] public void GetById_存在的ID_返回机床详情() { var id = InsertTestMachine(); var detail = _service.GetById(id); Assert.NotNull(detail); Assert.Equal("M001", detail.DeviceCode); Assert.Equal("测试机床", detail.Name); Assert.Equal(1, detail.WorkshopId); Assert.Equal(1, detail.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_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.GetById(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== Create ======== [Fact] public void Create_正常新增_返回自增ID() { var id = InsertTestMachine(); Assert.True(id > 0); } [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 CreateMachineRequest { DeviceCode = "", Name = "测试", WorkshopId = 1, BrandId = 1 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Create_设备编码为空格_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Create(new CreateMachineRequest { DeviceCode = " ", Name = "测试", WorkshopId = 1, BrandId = 1 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Create_重复设备编码_抛出Conflict异常() { InsertTestMachine("M001"); var ex = Assert.Throws(() => InsertTestMachine("M001")); Assert.Equal(ErrorCode.Conflict, ex.Code); } [Fact] public void Create_不同设备编码_成功() { var id1 = InsertTestMachine("M001"); var id2 = InsertTestMachine("M002"); Assert.NotEqual(id1, id2); } // ======== Update ======== [Fact] public void Update_正常修改_返回true() { var id = InsertTestMachine(); var result = _service.Update(id, new UpdateMachineRequest { Name = "修改后机床", WorkshopId = 2, IpAddress = "10.0.0.1", BrandId = 1, CollectAddressId = 1 // 使用已存在的采集地址 }); Assert.True(result); var updated = _service.GetById(id); Assert.Equal("修改后机床", updated.Name); Assert.Equal(2, updated.WorkshopId); } [Fact] public void Update_不存在的ID_抛出NotFound异常() { var ex = Assert.Throws(() => _service.Update(99999, new UpdateMachineRequest { Name = "测试", WorkshopId = 1, BrandId = 1, CollectAddressId = 0 })); Assert.Equal(ErrorCode.NotFound, ex.Code); } [Fact] public void Update_请求为null_抛出BadRequest异常() { var id = InsertTestMachine(); var ex = Assert.Throws(() => _service.Update(id, null)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } [Fact] public void Update_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.Update(0, new UpdateMachineRequest { Name = "测试", WorkshopId = 1, BrandId = 1, CollectAddressId = 0 })); Assert.Equal(ErrorCode.BadRequest, ex.Code); } // ======== Delete ======== [Fact] public void Delete_存在的ID_返回true() { var id = InsertTestMachine(); var result = _service.Delete(id); Assert.True(result); } [Fact] public void Delete_删除后查询不到() { var id = InsertTestMachine(); _service.Delete(id); Assert.Throws(() => _service.GetById(id)); } [Fact] public void Delete_同时解绑工人() { // 插入机床 var machineId = InsertTestMachine(); // 插入工人 TestDb.Execute(@"INSERT INTO cnc_worker (code, name, is_enabled, created_at, updated_at) VALUES ('W001', '工人1', 1, NOW(), NOW())"); // 绑定工人 TestDb.Execute(@"INSERT INTO cnc_worker_machine (worker_id, machine_id, created_at) VALUES (1, @machineId, NOW())", new { machineId }); // 删除机床 _service.Delete(machineId); // 验证绑定关系已删除 var count = TestDb.QuerySingle( "SELECT COUNT(*) FROM cnc_worker_machine WHERE machine_id = @machineId", new { machineId }); Assert.Equal(0, count); } [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 id = InsertTestMachine(); var before = _service.GetById(id); var beforeState = before.IsEnabled; _service.ToggleEnabled(id); var after = _service.GetById(id); Assert.NotEqual(beforeState, after.IsEnabled); } [Fact] public void ToggleEnabled_无效ID_抛出BadRequest异常() { var ex = Assert.Throws(() => _service.ToggleEnabled(0)); Assert.Equal(ErrorCode.BadRequest, ex.Code); } } }