Files
XplorePlane/XplorePlane.Tests/Hardware/SimulatedXRaySourceTests.cs
T
zhengxuan.zhang 94bfc5a705 fix(tests): 修复 SimulatedXRaySourceTests 因 VariablesConnectedEvent 未被 Mock 导致的失败
SimulatedXRaySource.ConnectVariables() 中新增的 VariablesConnectedEvent
发布未被测试的 EventAggregator Mock 覆盖,导致 GetEvent<T>() 返回 null,
触发 NullReferenceException,5 个测试全部失败。

- 补充 VariablesConnectedEvent、StatusUpdatedEvent 的 Mock 设置
- Initialize_SetsInitializedTrue 增加 VariablesConnectedEvent(true) 发布断言
- 修正 TurnOff_PublishesClosedEvent 断言逻辑:Arrange 阶段
  ConnectVariables/TurnOn 已产生一次 Closed 事件,需在 Act 前清空
  Invocations 避免误判发布次数
2026-07-15 09:57:19 +08:00

146 lines
5.2 KiB
C#

using Moq;
using Prism.Events;
using Xunit;
using XP.Common.Logging.Interfaces;
using XP.Hardware.RaySource.Abstractions.Enums;
using XP.Hardware.RaySource.Abstractions.Events;
using XP.Hardware.RaySource.Implementations;
namespace XplorePlane.Tests.Hardware
{
public class SimulatedXRaySourceTests
{
private readonly Mock<IEventAggregator> _mockEventAggregator;
private readonly Mock<ILoggerService> _mockLogger;
private readonly Mock<RaySourceStatusChangedEvent> _mockStatusEvent;
private readonly Mock<VariablesConnectedEvent> _mockVariablesConnectedEvent;
private readonly Mock<StatusUpdatedEvent> _mockStatusUpdatedEvent;
private readonly SimulatedXRaySource _source;
public SimulatedXRaySourceTests()
{
_mockEventAggregator = new Mock<IEventAggregator>();
_mockLogger = new Mock<ILoggerService>();
_mockStatusEvent = new Mock<RaySourceStatusChangedEvent>();
_mockVariablesConnectedEvent = new Mock<VariablesConnectedEvent>();
_mockStatusUpdatedEvent = new Mock<StatusUpdatedEvent>();
// Setup logger to return itself for ForModule<T>()
_mockLogger.Setup(l => l.ForModule<SimulatedXRaySource>()).Returns(_mockLogger.Object);
// Setup event aggregator to return the mock event
_mockEventAggregator
.Setup(ea => ea.GetEvent<RaySourceStatusChangedEvent>())
.Returns(_mockStatusEvent.Object);
// ConnectVariables() 会发布 VariablesConnectedEvent,需要 Mock 该事件避免 NullReferenceException
// ConnectVariables() publishes VariablesConnectedEvent, must mock it to avoid NullReferenceException
_mockEventAggregator
.Setup(ea => ea.GetEvent<VariablesConnectedEvent>())
.Returns(_mockVariablesConnectedEvent.Object);
// TurnOn/TurnOff/SetVoltage/SetCurrent 会发布 StatusUpdatedEvent,同样需要 Mock
// TurnOn/TurnOff/SetVoltage/SetCurrent publish StatusUpdatedEvent, also needs mocking
_mockEventAggregator
.Setup(ea => ea.GetEvent<StatusUpdatedEvent>())
.Returns(_mockStatusUpdatedEvent.Object);
_source = new SimulatedXRaySource(_mockEventAggregator.Object, _mockLogger.Object);
}
[Fact]
public void Initialize_SetsInitializedTrue()
{
// Act
var initResult = _source.Initialize();
var connectResult = _source.ConnectVariables();
// Assert
Assert.True(initResult.Success);
Assert.True(connectResult.Success);
Assert.True(_source.IsConnected);
// 验证 ConnectVariables 发布了 VariablesConnectedEvent(true)
// Verify ConnectVariables published VariablesConnectedEvent(true)
_mockVariablesConnectedEvent.Verify(e => e.Publish(true), Times.Once);
}
[Fact]
public void TurnOn_PublishesOpenedEvent()
{
// Arrange
_source.Initialize();
_source.ConnectVariables();
// Act
var result = _source.TurnOn();
// Assert
Assert.True(result.Success);
_mockStatusEvent.Verify(
e => e.Publish(RaySourceStatus.Opened),
Times.Once);
}
[Fact]
public void TurnOff_PublishesClosedEvent()
{
// Arrange
_source.Initialize();
_source.ConnectVariables();
_source.TurnOn();
// ConnectVariables/TurnOn 阶段已经发布过 Closed/Opened 事件,清空调用记录避免影响 Act 阶段的断言
// ConnectVariables/TurnOn already published Closed/Opened events during Arrange; clear invocations
// so the Act-phase assertion only counts the publish triggered by TurnOff()
_mockStatusEvent.Invocations.Clear();
// Act
var result = _source.TurnOff();
// Assert
Assert.True(result.Success);
_mockStatusEvent.Verify(
e => e.Publish(RaySourceStatus.Closed),
Times.Once);
}
[Fact]
public void ReadVoltage_ReturnsWithinTwoPercentOfSetValue()
{
// Arrange
_source.Initialize();
_source.ConnectVariables();
_source.SetVoltage(100f);
// Act & Assert - read multiple times to verify range
for (int i = 0; i < 20; i++)
{
var result = _source.ReadVoltage();
Assert.True(result.Success);
float voltage = result.GetFloat();
Assert.InRange(voltage, 98f, 102f);
}
}
[Fact]
public void CloseOff_ResetsState()
{
// Arrange
_source.Initialize();
_source.ConnectVariables();
_source.TurnOn();
Assert.True(_source.IsConnected);
// Act
var result = _source.CloseOff();
// Assert
Assert.True(result.Success);
Assert.False(_source.IsConnected);
}
}
}