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.True(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);
}
}
}