state-theory.cs

本文介绍了一个使用状态模式实现的简单游戏,通过上下操作改变游戏状态,并根据用户输入进行交互。游戏包含四个状态,每个状态有六种操作。
  using System;
  using System.Collections.Generic;

   // State Pattern               Judith Bishop  Oct 2007
   // Simple game where the context changes the state based on user input
   // Has four states, each with 6 operations
   
  interface IState {
    int MoveUp(Context context);
    int MoveDown(Context context);
  }

  // State 1
  class NormalState : IState {
    public  int MoveUp(Context context) {
      context.Counter+=2;
      return context.Counter;
    }

    public int MoveDown(Context context) {
        if (context.Counter < Context.limit) {
          context.State = new FastState();
          Console.Write("|| ");
        }
        context.Counter-=2;
        return context.Counter;
    }
  }

  // State 2
  class FastState : IState {
    public int MoveUp(Context context) {
      context.Counter+=5;
      return context.Counter;
    }

    public int MoveDown(Context context) {
       if (context.Counter < Context.limit) {
        context.State = new NormalState();
        Console.Write("||");
      }
      context.Counter-=5;
      return context.Counter;
    }
  }

  // Context
  class Context {
    public const int limit = 10;
    public IState State {get; set; }
    public int Counter = limit;
      
    public int Request(int n) {
      if (n==2)
        return State.MoveUp(this);
      else
        return State.MoveDown(this);
    }
  }
   
  static class Program {
     // The user interface
    static void Main () {
      Context context = new Context();
      context.State = new NormalState();
      Random r = new Random(37);
      for (int i = 5; i<=25; i++) {
        int command = r.Next(3);
        Console.Write(context.Request(command)+" ");
      }
      Console.WriteLine();
    }
  }
   /* Output
   8 10 8 || 6 11 16 11 6 ||1 3 || 1 ||-4 || -6 -1 4 ||-1 || -3 2 7 ||2 4
   */
 

Error and Warning messages D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\bin\Debug\net8.0-windows\MagneticDetectionSystem.dll 中没有可用测试。请确保已注册测试发现器和执行器且平台和框架版本设置合理,然后重试。 PS D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem> dotnet test --logger html --results-directory TestResults 在 0.6 秒内还原 成功,出现 1 警告 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\MagneticDetectionSystem.csproj : warning NU1701: 已使用“.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8, .NETFramework,Version=v4.8.1”而不是项目目标框架“net8.0-windows7.0”还原包“HelixToolkit.Wpf 2.25.0”。此包可能与项目不完全兼容。 MagneticDetectionSystem 成功,出现 39 警告 (0.9 秒) → bin\Debug\net8.0-windows\MagneticDetectionSystem.dll D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\MagneticDetectionSystem.csproj : warning NU1701: 已使用“.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8, .NETFramework,Version=v4.8.1”而不是项目目标框架“net8.0-windows7.0”还原包“HelixToolkit.Wpf 2.25.0”。此包可能与项目不完全兼容。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(493,30): warning CS8765: 参数“value”类型的为 Null 性与重写成员不匹配(可能是由于为 Null 性特性)。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(503,30): warning CS8765: 参数“value”类型的为 Null 性与重写成员不匹配(可能是由于为 Null 性特性)。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\App.xaml.cs(33,59): warning CS8603: 可能返回 null 引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\PortManager.cs(240,47): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\App.xaml.cs(244,29): warning CS8625: 无法将 null 字面量转换为非 null 的引用类型。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\PortManager.cs(368,25): warning CS8603: 可能返回 null 引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\PortManager.cs(372,25): warning CS8603: 可能返回 null 引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\App.xaml.cs(32,29): warning CS8618: 在退出构造函数时,不可为 null 的 属性 "_host" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 属性 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Views\MainWindow.xaml.cs(74,28): warning CS8602: 解引用可能出现空引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Core\StateHandlers\ScanningStateHandler.cs(163,28): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Core\StateHandlers\CalibratingStateHandler.cs(163,42): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\CrashDumpHandler.cs(41,65): warning CS8622: “void CrashDumpHandler.OnFirstChanceException(object sender, FirstChanceExceptionEventArgs e)”的参数“sender”类型中引用类型的为 Null 性与目标委托“EventHandler<FirstChanceExceptionEventArgs>”不匹配(可能是由于为 Null 性特性)。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\ViewModels\MainViewModel.cs(50,16): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_currentTime" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\CrashDumpHandler.cs(99,35): warning CS8604: “void CrashDumpHandler.GenerateCrashDump(Exception exception, string source)”中的形参“exception”可能传入 null 引用实参。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\StateMachineTests.cs(47,51): warning CS8602: 解引用可能出现空引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\StateMachineTests.cs(49,21): warning CS8620: 由于引用类型的可为 null 性差异,Func<It.IsAnyType, Exception, string> 类型的实参不能用于 void ILogger.Log<IsAnyType>(LogLevel logLevel, EventId eventId, IsAnyType state, Exception? exception, Func<IsAnyType, Exception?, string> formatter) 中 Func<It.IsAnyType, Exception?, string> 类型的形参 formatter。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\ViewModels\MainViewModel.cs(329,30): warning CS8604: “ILogger<SettingsWindow> LoggerFactoryExtensions.CreateLogger<SettingsWindow>(ILoggerFactory factory)”中的形参“factory”可能传入 null 引用实参。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\StateMachineTests.cs(169,51): warning CS8602: 解引用可能出现空引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\StateMachineTests.cs(171,21): warning CS8620: 由于引用类型的可为 null 性差异,Func<It.IsAnyType, Exception, string> 类型的实参不能用于 void ILogger.Log<IsAnyType>(LogLevel logLevel, EventId eventId, IsAnyType state, Exception? exception, Func<IsAnyType, Exception?, string> formatter) 中 Func<It.IsAnyType, Exception?, string> 类型的形参 formatter。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\CrashDumpHandler.cs(17,31): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_dumpDirectory" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\CommunicationServiceTests.cs(94,17): warning CS0219: 变量“eventTriggered”已被赋值,但从未使用过它的值 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\Communication\NetAdapterHelper.cs(31,53): warning CS8625: 无法将 null 字面量转换为非 null 的引用类型。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\Communication\NetAdapterHelper.cs(39,52): warning CS8625: 无法将 null 字面量转换为非 null 的引用类型。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\LaserSensor\LaserSensorService.cs(100,27): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\LaserSensor\LaserSensorService.cs(113,27): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\Storage\DataStorage.cs(489,31): warning CS8602: 解引用可能出现空引用。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(64,16): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_originalOutput" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(64,16): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_originalError" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(64,16): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_consoleThread" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(64,16): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_consoleWriter" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(80,66): warning CS8604: “ConsoleWindowManager.ConsoleWindowManager(ILogger<ConsoleWindowManager> logger)”中的形参“logger”可能传入 null 引用实参。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(588,30): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_writer" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(522,34): warning CS0168: 声明了变量“ex”,但从未使用过 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Modules\Communication\CommunicationService.cs(134,27): warning CS1998: 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\AlertManagerTests.cs(130,17): warning CS0219: 变量“initialEnabled”已被赋值,但从未使用过它的值 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\AlertManagerTests.cs(144,17): warning CS0219: 变量“initialEnabled”已被赋值,但从未使用过它的值 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Infrastructure\ConsoleWindowManager.cs(15,45): warning CS8618: 在退出构造函数时,不可为 null 的 字段 "_instance" 必须包含非 null 值。请考虑添加 "required" 修饰符或将该 字段 声明为可为 null。 D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\Tests\UnitTests\DataStorageTests.cs(320,21): warning xUnit1013: Public method 'Dispose' on test class 'DataStorageTests' should be marked as a Fact. Reduce the visibility of the method, or add a Fact attribute to the method. (https://xunit.net/xunit.analyzers/rules/xUnit1013) HTML 测试结果文件: D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\TestResults\TestResult_Lenovo_LAPTOP-FFJ6O84V_20251111_112800.html 此外,还可以使用 /TestAdapterPath 命令指定测试适配器的路径。示例 /TestAdapterPath:<pathToCustomAdapters>。 MagneticDetectionSystem 测试 成功,出现 1 警告 (0.7 秒) C:\Program Files\dotnet\sdk\9.0.306\Microsoft.TestPlatform.targets(48,5): warning : D:\05-CODE\Weak_MF_measurement_Up_CQJB\CQJBApp\MagneticDetectionSystem\bin\Debug\net8.0-windows\MagneticDetectionSystem.dll 中没有可用测试。请确保已注册测试发现器和执行器且平台和框架版本设置合理,然后重试。
最新发布
11-12
如何运行单元测试 using System; using System.Threading.Tasks; using MagneticDetectionSystem.Core; using MagneticDetectionSystem.Core.Enums; using MagneticDetectionSystem.Core.Interfaces; using Microsoft.Extensions.Logging; using Moq; using Xunit; namespace MagneticDetectionSystem.Tests.UnitTests { public class StateMachineTests { private readonly Mock<ILogger<StateMachine>> _loggerMock; private readonly StateMachine _stateMachine; public StateMachineTests() { _loggerMock = new Mock<ILogger<StateMachine>>(); _stateMachine = new StateMachine(_loggerMock.Object); } [Fact] public async Task StartAsync_ShouldSetRunningState() { // Act await _stateMachine.StartAsync(); // Assert Assert.Equal(SystemState.Idle, _stateMachine.CurrentState); } [Fact] public async Task StartAsync_WhenAlreadyRunning_ShouldLogWarning() { // Arrange await _stateMachine.StartAsync(); // Act await _stateMachine.StartAsync(); // Assert _loggerMock.Verify( x => x.Log( LogLevel.Warning, It.IsAny<EventId>(), It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("already running")), It.IsAny<Exception>(), It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Once); } [Fact] public async Task StopAsync_ShouldSetStoppedState() { // Arrange await _stateMachine.StartAsync(); // Act await _stateMachine.StopAsync(); // Assert Assert.Equal(SystemState.Idle, _stateMachine.CurrentState); } [Fact] public async Task StopAsync_WhenNotRunning_ShouldDoNothing() { // Act await _stateMachine.StopAsync(); // Assert Assert.Equal(SystemState.Idle, _stateMachine.CurrentState); } [Fact] public async Task TransitionToAsync_WithValidState_ShouldChangeState() { // Arrange await _stateMachine.StartAsync(); // Act await _stateMachine.TransitionToAsync(SystemState.Ready); // Assert Assert.Equal(SystemState.Ready, _stateMachine.CurrentState); } [Fact] public async Task TransitionToAsync_WithSameState_ShouldDoNothing() { // Arrange await _stateMachine.StartAsync(); var initialState = _stateMachine.CurrentState; // Act await _stateMachine.TransitionToAsync(initialState); // Assert Assert.Equal(initialState, _stateMachine.CurrentState); } [Fact] public async Task TransitionToAsync_WhenNotRunning_ShouldThrowException() { // Act & Assert await Assert.ThrowsAsync<InvalidOperationException>(() => _stateMachine.TransitionToAsync(SystemState.Ready)); } [Fact] public async Task HandleEventAsync_WithStartEvent_ShouldTransitionToInitializing() { // Arrange await _stateMachine.StartAsync(); var stateChanged = false; _stateMachine.StateChanged += (sender, args) => { if (args.NewState == SystemState.Initializing) { stateChanged = true; } }; // Act await _stateMachine.HandleEventAsync(new StartEvent()); // Assert Assert.True(stateChanged); } [Fact] public async Task HandleEventAsync_WithErrorEvent_ShouldTransitionToError() { // Arrange await _stateMachine.StartAsync(); var stateChanged = false; _stateMachine.StateChanged += (sender, args) => { if (args.NewState == SystemState.Error) { stateChanged = true; } }; // Act await _stateMachine.HandleEventAsync(new ErrorEvent { Exception = new Exception("Test error") }); // Assert Assert.True(stateChanged); } [Fact] public async Task HandleEventAsync_WhenNotRunning_ShouldLogWarning() { // Act await _stateMachine.HandleEventAsync(new StartEvent()); // Assert _loggerMock.Verify( x => x.Log( LogLevel.Warning, It.IsAny<EventId>(), It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("not running")), It.IsAny<Exception>(), It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Once); } [Fact] public void RegisterStateHandler_ShouldRegisterHandler() { // Arrange var handlerMock = new Mock<IStateHandler>(); handlerMock.Setup(h => h.State).Returns(SystemState.Ready); // Act _stateMachine.RegisterStateHandler(SystemState.Ready, handlerMock.Object); // Assert // 无法直接验证,但方法应该正常执行 Assert.True(true); } [Fact] public async Task StateChanged_ShouldTriggerEvent() { // Arrange await _stateMachine.StartAsync(); var eventTriggered = false; StateChangedEventArgs? eventArgs = null; _stateMachine.StateChanged += (sender, args) => { eventTriggered = true; eventArgs = args; }; // Act await _stateMachine.TransitionToAsync(SystemState.Ready); // Assert Assert.True(eventTriggered); Assert.NotNull(eventArgs); Assert.Equal(SystemState.Idle, eventArgs!.OldState); Assert.Equal(SystemState.Ready, eventArgs.NewState); } [Fact] public async Task TransitionToAsync_WithError_ShouldTransitionToErrorState() { // Arrange await _stateMachine.StartAsync(); // 注册一个会抛出异常的状态处理器 var handlerMock = new Mock<IStateHandler>(); handlerMock.Setup(h => h.State).Returns(SystemState.Ready); handlerMock.Setup(h => h.OnEnterAsync(It.IsAny<SystemState>())) .ThrowsAsync(new Exception("Test exception")); _stateMachine.RegisterStateHandler(SystemState.Ready, handlerMock.Object); // Act & Assert await Assert.ThrowsAsync<Exception>(() => _stateMachine.TransitionToAsync(SystemState.Ready)); Assert.Equal(SystemState.Error, _stateMachine.CurrentState); } [Fact] public async Task HandleEventAsync_WithException_ShouldTriggerErrorEvent() { // Arrange await _stateMachine.StartAsync(); var errorStateReached = false; _stateMachine.StateChanged += (sender, args) => { if (args.NewState == SystemState.Error) { errorStateReached = true; } }; // 注册一个会抛出异常的状态处理器 var handlerMock = new Mock<IStateHandler>(); handlerMock.Setup(h => h.State).Returns(SystemState.Ready); handlerMock.Setup(h => h.HandleEventAsync(It.IsAny<SystemEvent>())) .ThrowsAsync(new Exception("Test exception")); await _stateMachine.TransitionToAsync(SystemState.Ready); _stateMachine.RegisterStateHandler(SystemState.Ready, handlerMock.Object); // Act await _stateMachine.HandleEventAsync(new StartEvent()); // Assert Assert.True(errorStateReached); } } }
11-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值