You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

367 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Xunit;
using Haoliang.Models.Device;
using Haoliang.Models.DataCollection;
using Haoliang.Core.Services;
namespace Haoliang.Tests
{
public class DeviceCollectionServiceTests
{
private readonly IDeviceCollectionService _collectionService;
public DeviceCollectionServiceTests()
{
// 这里应该使用mock对象或测试数据库
_collectionService = new DeviceCollectionService(null, null, null, null, null, null);
}
[Fact]
public async Task CollectDeviceDataAsync_ShouldParseValidJson()
{
// Arrange
var sampleJson = @"{
""device"": ""FANUC_01"",
""desc"": ""CNC Machine"",
""tags"": [
{
""id"": ""_io_status"",
""desc"": ""I/O Status"",
""quality"": 0,
""value"": 1,
""time"": ""2024-01-01T10:00:00""
},
{
""id"": ""Tag5"",
""desc"": ""NC Program"",
""quality"": 0,
""value"": ""O1234"",
""time"": ""2024-01-01T10:00:00""
},
{
""id"": ""Tag8"",
""desc"": ""Cumulative Count"",
""quality"": 0,
""value"": 12345.00000,
""time"": ""2024-01-01T10:00:00""
}
]
}";
// Act
var result = await _collectionService.CollectDeviceDataAsync(1);
// Assert
Assert.NotNull(result);
Assert.Equal("FANUC_01", result.DeviceCode);
Assert.Equal("O1234", result.NCProgram);
Assert.Equal(12345, result.CumulativeCount);
}
[Fact]
public async Task CollectDeviceDataAsync_ShouldHandleInvalidJson()
{
// Arrange
var invalidJson = @"{
""device"": ""FANUC_01"",
""desc"": ""CNC Machine"",
""tags"": [
{
""id"": ""invalid_tag"",
""value"": ""invalid_value""
}
]
}";
// Act & Assert
await Assert.ThrowsAsync<JsonException>(() =>
_collectionService.CollectDeviceDataAsync(1));
}
[Fact]
public async Task PingDeviceAsync_ShouldReturnTrueForValidIp()
{
// Arrange
var validIp = "8.8.8.8"; // Google DNS
// Act
var result = await _collectionService.PingDeviceAsync(validIp);
// Assert
Assert.True(result);
}
}
public class ProductionServiceTests
{
private readonly IProductionService _productionService;
public ProductionServiceTests()
{
_productionService = new ProductionService(null, null, null);
}
[Fact]
public async Task CalculateProductionAsync_ShouldCalculateDifference()
{
// Arrange
var current = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O1234",
CumulativeCount = 15000,
RecordTime = DateTime.Now
};
var last = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O1234",
CumulativeCount = 12000,
RecordTime = DateTime.Now.AddMinutes(-5)
};
// Act
var result = await _productionService.CalculateProductionAsync(1);
// Assert
Assert.Equal(3000, result);
}
[Fact]
public async Task CalculateProductionAsync_ShouldHandleNegativeValues()
{
// Arrange
var current = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O1234",
CumulativeCount = 10000,
RecordTime = DateTime.Now
};
var last = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O1234",
CumulativeCount = 12000, // 比当前值大,应该产生负数
RecordTime = DateTime.Now.AddMinutes(-5)
};
// Act
var result = await _productionService.CalculateProductionAsync(1);
// Assert
Assert.Equal(0, result); // 负数应该被保护为0
}
[Fact]
public async Task CalculateProductionAsync_ShouldHandleProgramSwitch()
{
// Arrange
var current = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O5678", // 不同的程序
CumulativeCount = 20000,
RecordTime = DateTime.Now
};
var last = new DeviceCurrentStatus
{
DeviceId = 1,
NCProgram = "O1234",
CumulativeCount = 15000,
RecordTime = DateTime.Now.AddMinutes(-5)
};
// Act
var result = await _productionService.CalculateProductionAsync(1);
// Assert
Assert.Equal(20000, result); // 新程序以当前累计数为起点
}
}
public class AlarmServiceTests
{
private readonly IAlarmService _alarmService;
public AlarmServiceTests()
{
_alarmService = new AlarmManager(null, null, null);
}
[Fact]
public async Task CreateAlarmAsync_ShouldCreateAlarm()
{
// Arrange
var alarm = new Alarm
{
DeviceId = 1,
DeviceCode = "FANUC_01",
AlarmType = AlarmType.DeviceOffline,
Severity = AlarmSeverity.Critical,
Title = "Device Offline",
Description = "The device has been offline for more than 5 minutes",
AlarmStatus = AlarmStatus.Active
};
// Act
var result = await _alarmService.CreateAlarmAsync(alarm);
// Assert
Assert.NotNull(result);
Assert.Equal(AlarmStatus.Active, result.AlarmStatus);
Assert.NotNull(result.CreateTime);
}
[Fact]
public async Task ResolveAlarmAsync_ShouldMarkAsResolved()
{
// Arrange
var alarm = new Alarm
{
DeviceId = 1,
DeviceCode = "FANUC_01",
AlarmType = AlarmType.DeviceOffline,
Severity = AlarmSeverity.Warning,
Title = "Device Offline",
Description = "The device has been offline",
AlarmStatus = AlarmStatus.Active
};
var createdAlarm = await _alarmService.CreateAlarmAsync(alarm);
// Act
var result = await _alarmService.ResolveAlarmAsync(createdAlarm.AlarmId, "Device reconnected");
// Assert
Assert.True(result);
// 验证状态确实改变了
var resolvedAlarm = await _alarmService.GetAlarmByIdAsync(createdAlarm.AlarmId);
Assert.Equal(AlarmStatus.Resolved, resolvedAlarm.AlarmStatus);
Assert.NotNull(resolvedAlarm.ResolvedTime);
Assert.Equal("Device reconnected", resolvedAlarm.ResolutionNote);
}
}
public class TemplateServiceTests
{
private readonly ITemplateService _templateService;
public TemplateServiceTests()
{
_templateService = new TemplateManager(null, null, null, null);
}
[Fact]
public async Task CreateTemplateAsync_ShouldCreateValidTemplate()
{
// Arrange
var template = new CNCBrandTemplate
{
TemplateName = "FANUC Standard",
BrandName = "FANUC",
Description = "Standard FANUC template",
IsEnabled = true,
Version = "1.0",
TemplateJson = @"{
""device"": {
""status"": ""_io_status""
},
""production"": {
""program"": ""Tag5"",
""count"": ""Tag8""
}
}"
};
// Act
var result = await _templateService.CreateTemplateAsync(template);
// Assert
Assert.NotNull(result);
Assert.Equal("FANUC Standard", result.TemplateName);
Assert.True(result.IsEnabled);
Assert.NotNull(result.CreateTime);
}
[Fact]
public async Task ValidateTemplateAsync_ShouldRejectInvalidTemplate()
{
// Arrange
var invalidTemplate = new CNCBrandTemplate
{
TemplateName = "", // 空模板名
BrandName = "FANUC",
Description = "Invalid template",
IsEnabled = true,
Version = "1.0",
TemplateJson = "" // 空JSON
};
// Act
var result = await _templateService.ValidateTemplateAsync(invalidTemplate);
// Assert
Assert.False(result);
}
}
public class SystemServiceTests
{
private readonly ISystemConfigService _configService;
private readonly ILoggingService _loggingService;
public SystemServiceTests()
{
_configService = new SystemConfigManager(null, null);
_loggingService = new LoggingManager(null, null);
}
[Fact]
public async Task GetConfigAsync_ShouldReturnExistingConfig()
{
// Arrange
await _configService.SetConfigAsync("test.config", "test.value");
// Act
var result = await _configService.GetConfigAsync("test.config");
// Assert
Assert.NotNull(result);
Assert.Equal("test.value", result.ConfigValue);
}
[Fact]
public async Task SetConfigAsync_ShouldUpdateConfig()
{
// Arrange
var newConfig = await _configService.SetConfigAsync("test.config", "new.value");
// Act
var result = await _configService.GetConfigAsync("test.config");
// Assert
Assert.NotNull(result);
Assert.Equal("new.value", result.ConfigValue);
}
[Fact]
public async Task LogAsync_ShouldLogMessage()
{
// Arrange
var message = "Test log message";
// Act
await _loggingService.LogAsync(LogLevel.Information, message);
// 这里可以添加数据库验证,检查日志是否正确存储
}
}
}