|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using CncModels.Dto;
|
|
|
using CncModels.Dto.Worker;
|
|
|
using CncService;
|
|
|
using CncWebApi.Controllers;
|
|
|
using Xunit;
|
|
|
|
|
|
namespace CncWebApi.Tests
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// WorkerController单元测试
|
|
|
/// 员工CRUD + 启停 + 绑定/解绑机床
|
|
|
/// </summary>
|
|
|
[Collection("Database")]
|
|
|
public class WorkerControllerTests
|
|
|
{
|
|
|
private readonly WorkerController _controller;
|
|
|
|
|
|
public WorkerControllerTests()
|
|
|
{
|
|
|
TestDb.TruncateAll();
|
|
|
// 预置采集地址+机床(绑定/解绑测试需要)
|
|
|
TestDb.Execute(@"INSERT INTO cnc_collect_address (name, url, brand_id, collect_interval, is_enabled, created_at, updated_at)
|
|
|
VALUES ('测试地址', 'http://192.168.1.1', 1, 5, 1, NOW(), NOW())");
|
|
|
TestDb.Execute(@"INSERT INTO cnc_machine (device_code, name, workshop_id, collect_address_id, ip_address, brand_id, is_enabled, created_at, updated_at)
|
|
|
VALUES ('CNC001', '机床1', 1, 1, '192.168.1.100', 1, 1, NOW(), NOW())");
|
|
|
_controller = ControllerFactory.CreateWorkerController();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 辅助:创建工人请求
|
|
|
/// </summary>
|
|
|
private CreateWorkerRequest CreateRequest(string name = "张三", string code = "W001") => new CreateWorkerRequest
|
|
|
{
|
|
|
Name = name,
|
|
|
Code = code
|
|
|
};
|
|
|
|
|
|
#region GetList - 工人列表
|
|
|
|
|
|
[Fact]
|
|
|
public void GetList_EmptyDb_ShouldReturnEmpty()
|
|
|
{
|
|
|
var result = _controller.GetList(new WorkerQuery());
|
|
|
var response = ControllerFactory.Extract<PagedResult<WorkerListItem>>(result);
|
|
|
ControllerFactory.AssertSuccess(response);
|
|
|
Assert.Empty(response.Data.Items);
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void GetList_AfterCreate_ShouldReturnOne()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
var result = _controller.GetList(new WorkerQuery());
|
|
|
var response = ControllerFactory.Extract<PagedResult<WorkerListItem>>(result);
|
|
|
Assert.Single(response.Data.Items);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region GetById - 工人详情
|
|
|
|
|
|
[Fact]
|
|
|
public void GetById_Existing_ShouldReturnDetail()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
|
|
|
var result = _controller.GetById(id);
|
|
|
var response = ControllerFactory.Extract<WorkerDetailResponse>(result);
|
|
|
ControllerFactory.AssertSuccess(response);
|
|
|
Assert.Equal("张三", response.Data.Name);
|
|
|
Assert.Equal("W001", response.Data.Code);
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void GetById_NotExisting_ShouldThrow()
|
|
|
{
|
|
|
Assert.Throws<BusinessException>(() => _controller.GetById(999));
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Create - 新增工人
|
|
|
|
|
|
[Fact]
|
|
|
public void Create_ValidRequest_ShouldReturnId()
|
|
|
{
|
|
|
var result = _controller.Create(CreateRequest());
|
|
|
var response = ControllerFactory.Extract<object>(result);
|
|
|
ControllerFactory.AssertSuccess(response);
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void Create_DuplicateCode_ShouldThrow()
|
|
|
{
|
|
|
_controller.Create(CreateRequest("张三", "W001"));
|
|
|
var ex = Assert.Throws<BusinessException>(() => _controller.Create(CreateRequest("李四", "W001")));
|
|
|
Assert.Equal("工号已存在", ex.Message);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Update - 编辑工人
|
|
|
|
|
|
[Fact]
|
|
|
public void Update_ValidRequest_ShouldSuccess()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
|
|
|
var result = _controller.Update(id, new UpdateWorkerRequest { Name = "张三改名" });
|
|
|
ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
|
|
|
|
|
|
var detail = ControllerFactory.Extract<WorkerDetailResponse>(_controller.GetById(id));
|
|
|
Assert.Equal("张三改名", detail.Data.Name);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region Delete - 删除工人
|
|
|
|
|
|
[Fact]
|
|
|
public void Delete_Existing_ShouldSuccess()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
|
|
|
var result = _controller.Delete(id);
|
|
|
ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void Delete_NotExisting_ShouldNotThrow()
|
|
|
{
|
|
|
// Service层删除不存在ID时影响0行但不抛异常
|
|
|
var result = _controller.Delete(999);
|
|
|
Assert.NotNull(result);
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region ToggleEnabled - 启停
|
|
|
|
|
|
[Fact]
|
|
|
public void ToggleEnabled_ShouldSuccess()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
int id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
|
|
|
var result = _controller.ToggleEnabled(id);
|
|
|
ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
#region BindMachine / UnbindMachine - 绑定/解绑
|
|
|
|
|
|
[Fact]
|
|
|
public void BindMachine_ShouldSuccess()
|
|
|
{
|
|
|
_controller.Create(CreateRequest());
|
|
|
int workerId = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
|
|
|
var result = _controller.BindMachine(workerId, new BindMachineRequest { MachineId = 1 });
|
|
|
ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void UnbindMachine_ShouldSuccess()
|
|
|
{
|
|
|
// 先绑定
|
|
|
_controller.Create(CreateRequest());
|
|
|
int workerId = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_worker");
|
|
|
_controller.BindMachine(workerId, new BindMachineRequest { MachineId = 1 });
|
|
|
|
|
|
// 再解绑
|
|
|
var result = _controller.UnbindMachine(workerId, new BindMachineRequest { MachineId = 1 });
|
|
|
ControllerFactory.AssertSuccess(ControllerFactory.Extract<object>(result));
|
|
|
}
|
|
|
|
|
|
[Fact]
|
|
|
public void BindMachine_NotExistingWorker_ShouldThrowDbException()
|
|
|
{
|
|
|
// 不存在的worker_id会触发外键约束,抛出MySqlException而非BusinessException
|
|
|
Assert.ThrowsAny<Exception>(() =>
|
|
|
_controller.BindMachine(999, new BindMachineRequest { MachineId = 1 }));
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
}
|
|
|
}
|