A:配置读取
This commit is contained in:
1 parent
859814514b
commit
727c83da2d
13 files changed
+671
-32
No files matched your search
@@ -0,0 +1,643 @@
|
||||
namespace Common.Test;
|
||||
|
||||
/// <summary>
|
||||
/// Global 轻量级 DI 容器测试
|
||||
/// 展示了依赖注入容器的所有功能和使用场景
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class GlobalTests
|
||||
{
|
||||
/// <summary>
|
||||
/// 每个测试方法执行前清除所有注册的服务,确保测试隔离
|
||||
/// </summary>
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
Global.Clear();
|
||||
}
|
||||
|
||||
#region 基础注册和获取测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试:注册并获取单例服务实例
|
||||
/// 演示最基本的服务注册和获取
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void RegisterSingleton_WithInstance_CanGetSameInstance()
|
||||
{
|
||||
// Arrange: 创建一个配置对象
|
||||
var config = new AppConfig { AppName = "MyApp", Version = "1.0" };
|
||||
|
||||
// Act: 注册为单例
|
||||
Global.RegisterSingleton(config);
|
||||
var retrieved = Global.Get<AppConfig>();
|
||||
|
||||
// Assert: 应该返回同一个实例
|
||||
Assert.AreSame(config, retrieved);
|
||||
Assert.AreEqual("MyApp", retrieved.AppName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:使用工厂方法注册单例
|
||||
/// 演示延迟初始化,只有在第一次 Get 时才会调用工厂方法
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void RegisterSingleton_WithFactory_CreatesInstanceOnFirstGet()
|
||||
{
|
||||
// Arrange: 创建一个计数器来跟踪工厂方法被调用的次数
|
||||
var factoryCallCount = 0;
|
||||
|
||||
// Act: 使用工厂方法注册
|
||||
Global.RegisterSingleton(() =>
|
||||
{
|
||||
factoryCallCount++;
|
||||
return new AppConfig { AppName = "FactoryApp" };
|
||||
});
|
||||
|
||||
// Assert: 工厂方法还未被调用
|
||||
Assert.AreEqual(0, factoryCallCount);
|
||||
|
||||
// Act: 第一次获取
|
||||
var first = Global.Get<AppConfig>();
|
||||
Assert.AreEqual(1, factoryCallCount); // 工厂方法被调用了一次
|
||||
|
||||
// Act: 第二次获取
|
||||
var second = Global.Get<AppConfig>();
|
||||
Assert.AreEqual(1, factoryCallCount); // 工厂方法没有再次调用
|
||||
Assert.AreSame(first, second); // 返回的是同一个实例
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:注册瞬态服务,每次获取都创建新实例
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void RegisterTransient_CreatesNewInstanceEachTime()
|
||||
{
|
||||
// Arrange & Act: 注册瞬态服务
|
||||
Global.RegisterTransient(() => new RequestContext
|
||||
{
|
||||
RequestId = Guid.NewGuid().ToString(),
|
||||
Timestamp = DateTime.Now
|
||||
});
|
||||
|
||||
// Act: 多次获取
|
||||
var first = Global.Get<RequestContext>();
|
||||
var second = Global.Get<RequestContext>();
|
||||
var third = Global.Get<RequestContext>();
|
||||
|
||||
// Assert: 每次都是不同的实例
|
||||
Assert.AreNotSame(first, second);
|
||||
Assert.AreNotSame(second, third);
|
||||
Assert.AreNotEqual(first.RequestId, second.RequestId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:使用通用 Register 方法指定生命周期
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Register_WithLifetime_CreatesCorrectLifetime()
|
||||
{
|
||||
// Arrange & Act: 使用通用方法注册单例
|
||||
Global.Register(() => new CacheService(), ServiceLifetime.Singleton);
|
||||
var cache1 = Global.Get<CacheService>();
|
||||
var cache2 = Global.Get<CacheService>();
|
||||
|
||||
// Assert: 单例应该是同一个实例
|
||||
Assert.AreSame(cache1, cache2);
|
||||
|
||||
// Arrange & Act: 使用通用方法注册瞬态
|
||||
Global.Register(() => new OperationContext(), ServiceLifetime.Transient);
|
||||
var op1 = Global.Get<OperationContext>();
|
||||
var op2 = Global.Get<OperationContext>();
|
||||
|
||||
// Assert: 瞬态应该是不同实例
|
||||
Assert.AreNotSame(op1, op2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 服务获取测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试:获取未注册的服务会抛出异常
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Get_UnregisteredService_ThrowsException()
|
||||
{
|
||||
// Act & Assert: 尝试获取未注册的服务应该抛出异常
|
||||
var exception = Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
Global.Get<ILogger>();
|
||||
});
|
||||
|
||||
Assert.IsTrue(exception.Message.Contains("ILogger"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:TryGet 安全地尝试获取服务
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TryGet_UnregisteredService_ReturnsFalse()
|
||||
{
|
||||
// Act: 尝试获取未注册的服务
|
||||
var success = Global.TryGet<ILogger>(out var logger);
|
||||
|
||||
// Assert: 应该返回 false 且 logger 为 null
|
||||
Assert.IsFalse(success);
|
||||
Assert.IsNull(logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:TryGet 成功获取已注册的服务
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void TryGet_RegisteredService_ReturnsTrue()
|
||||
{
|
||||
// Arrange: 注册服务
|
||||
var expectedLogger = new ConsoleLogger();
|
||||
Global.RegisterSingleton<ILogger>(expectedLogger);
|
||||
|
||||
// Act: 尝试获取
|
||||
var success = Global.TryGet<ILogger>(out var logger);
|
||||
|
||||
// Assert: 应该成功获取
|
||||
Assert.IsTrue(success);
|
||||
Assert.IsNotNull(logger);
|
||||
Assert.AreSame(expectedLogger, logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:GetOrDefault 获取服务或返回默认值
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetOrDefault_UnregisteredService_ReturnsDefault()
|
||||
{
|
||||
// Arrange: 创建默认值
|
||||
var defaultLogger = new ConsoleLogger();
|
||||
|
||||
// Act: 获取未注册的服务
|
||||
var logger = Global.GetOrDefault(defaultLogger);
|
||||
|
||||
// Assert: 应该返回默认值
|
||||
Assert.AreSame(defaultLogger, logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:GetOrDefault 获取已注册的服务而不是默认值
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void GetOrDefault_RegisteredService_ReturnsService()
|
||||
{
|
||||
// Arrange: 注册服务
|
||||
var registeredLogger = new ConsoleLogger();
|
||||
Global.RegisterSingleton<ILogger>(registeredLogger);
|
||||
var defaultLogger = new ConsoleLogger();
|
||||
|
||||
// Act: 获取服务
|
||||
var logger = Global.GetOrDefault(defaultLogger);
|
||||
|
||||
// Assert: 应该返回注册的服务,而不是默认值
|
||||
Assert.AreSame(registeredLogger, logger);
|
||||
Assert.AreNotSame(defaultLogger, logger);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 服务更新和变更通知测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试:更新单例服务实例
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Update_SingletonService_UpdatesInstance()
|
||||
{
|
||||
// Arrange: 注册初始配置
|
||||
var oldConfig = new AppConfig { AppName = "OldApp", Version = "1.0" };
|
||||
Global.RegisterSingleton(oldConfig);
|
||||
|
||||
// Act: 更新配置
|
||||
var newConfig = new AppConfig { AppName = "NewApp", Version = "2.0" };
|
||||
Global.Update(newConfig);
|
||||
|
||||
// Assert: 获取的应该是新配置
|
||||
var retrieved = Global.Get<AppConfig>();
|
||||
Assert.AreSame(newConfig, retrieved);
|
||||
Assert.AreEqual("NewApp", retrieved.AppName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:更新瞬态服务会抛出异常
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Update_TransientService_ThrowsException()
|
||||
{
|
||||
// Arrange: 注册瞬态服务
|
||||
Global.RegisterTransient(() => new RequestContext());
|
||||
|
||||
// Act & Assert: 尝试更新瞬态服务应该抛出异常
|
||||
Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
Global.Update(new RequestContext());
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:订阅服务变更通知
|
||||
/// 演示如何监听服务变更事件
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Subscribe_ServiceChange_ReceivesNotification()
|
||||
{
|
||||
// Arrange: 设置事件处理器
|
||||
ServiceChangedEventArgs<AppConfig>? receivedEventArgs = null;
|
||||
var callCount = 0;
|
||||
|
||||
Global.Subscribe<AppConfig>(e =>
|
||||
{
|
||||
receivedEventArgs = e;
|
||||
callCount++;
|
||||
});
|
||||
|
||||
// Act: 注册初始服务
|
||||
var oldConfig = new AppConfig { AppName = "OldApp", Version = "1.0" };
|
||||
Global.RegisterSingleton(oldConfig);
|
||||
|
||||
// 第一次注册不会触发通知(因为没有旧值)
|
||||
Assert.AreEqual(0, callCount);
|
||||
|
||||
// Act: 更新服务
|
||||
var newConfig = new AppConfig { AppName = "NewApp", Version = "2.0" };
|
||||
Global.Update(newConfig);
|
||||
|
||||
// Assert: 应该收到通知
|
||||
Assert.AreEqual(1, callCount);
|
||||
Assert.IsNotNull(receivedEventArgs);
|
||||
Assert.AreSame(oldConfig, receivedEventArgs.OldValue);
|
||||
Assert.AreSame(newConfig, receivedEventArgs.NewValue);
|
||||
Assert.AreEqual("OldApp", receivedEventArgs.OldValue?.AppName);
|
||||
Assert.AreEqual("NewApp", receivedEventArgs.NewValue.AppName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:多个订阅者都能收到通知
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Subscribe_MultipleSubscribers_AllReceiveNotifications()
|
||||
{
|
||||
// Arrange: 创建多个订阅者
|
||||
var subscriber1Called = false;
|
||||
var subscriber2Called = false;
|
||||
var subscriber3Called = false;
|
||||
|
||||
Global.Subscribe<AppConfig>(e => subscriber1Called = true);
|
||||
Global.Subscribe<AppConfig>(e => subscriber2Called = true);
|
||||
Global.Subscribe<AppConfig>(e => subscriber3Called = true);
|
||||
|
||||
// Act: 注册并更新服务
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "App", Version = "1.0" });
|
||||
Global.Update(new AppConfig { AppName = "App", Version = "2.0" });
|
||||
|
||||
// Assert: 所有订阅者都应该收到通知
|
||||
Assert.IsTrue(subscriber1Called);
|
||||
Assert.IsTrue(subscriber2Called);
|
||||
Assert.IsTrue(subscriber3Called);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:取消订阅后不再收到通知
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Unsubscribe_RemovesSubscriber()
|
||||
{
|
||||
// Arrange: 订阅通知
|
||||
var callCount = 0;
|
||||
void Handler(ServiceChangedEventArgs<AppConfig> e) => callCount++;
|
||||
|
||||
Global.Subscribe<AppConfig>(Handler);
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "App", Version = "1.0" });
|
||||
|
||||
// Act: 更新一次(应该收到通知)
|
||||
Global.Update(new AppConfig { AppName = "App", Version = "2.0" });
|
||||
Assert.AreEqual(1, callCount);
|
||||
|
||||
// Act: 取消订阅
|
||||
Global.Unsubscribe<AppConfig>(Handler);
|
||||
|
||||
// Act: 再次更新(不应该收到通知)
|
||||
Global.Update(new AppConfig { AppName = "App", Version = "3.0" });
|
||||
Assert.AreEqual(1, callCount); // 计数没有增加
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:注册时启用 notifyIfExists 会触发通知
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void RegisterSingleton_WithNotifyIfExists_TriggersNotification()
|
||||
{
|
||||
// Arrange: 订阅通知
|
||||
var notificationCount = 0;
|
||||
Global.Subscribe<AppConfig>(e => notificationCount++);
|
||||
|
||||
// Act: 第一次注册
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "App", Version = "1.0" });
|
||||
Assert.AreEqual(0, notificationCount); // 首次注册不触发
|
||||
|
||||
// Act: 使用 notifyIfExists = true 再次注册
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "App", Version = "2.0" }, notifyIfExists: true);
|
||||
|
||||
// Assert: 应该触发通知
|
||||
Assert.AreEqual(1, notificationCount);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 服务管理测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试:检查服务是否已注册
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void IsRegistered_ChecksServiceRegistration()
|
||||
{
|
||||
// Assert: 初始未注册
|
||||
Assert.IsFalse(Global.IsRegistered<AppConfig>());
|
||||
|
||||
// Act: 注册服务
|
||||
Global.RegisterSingleton(new AppConfig());
|
||||
|
||||
// Assert: 现在已注册
|
||||
Assert.IsTrue(Global.IsRegistered<AppConfig>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:注销服务
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Unregister_RemovesService()
|
||||
{
|
||||
// Arrange: 注册服务
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "TestApp" });
|
||||
Assert.IsTrue(Global.IsRegistered<AppConfig>());
|
||||
|
||||
// Act: 注销服务
|
||||
var result = Global.Unregister<AppConfig>();
|
||||
|
||||
// Assert: 服务已被移除
|
||||
Assert.IsTrue(result);
|
||||
Assert.IsFalse(Global.IsRegistered<AppConfig>());
|
||||
|
||||
// 尝试获取应该失败
|
||||
Assert.ThrowsException<InvalidOperationException>(() =>
|
||||
{
|
||||
Global.Get<AppConfig>();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:清除所有服务
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Clear_RemovesAllServices()
|
||||
{
|
||||
// Arrange: 注册多个服务
|
||||
Global.RegisterSingleton(new AppConfig());
|
||||
Global.RegisterSingleton<ILogger>(new ConsoleLogger());
|
||||
Global.RegisterTransient(() => new RequestContext());
|
||||
|
||||
Assert.AreEqual(3, Global.Count);
|
||||
|
||||
// Act: 清除所有服务
|
||||
Global.Clear();
|
||||
|
||||
// Assert: 所有服务都被移除
|
||||
Assert.AreEqual(0, Global.Count);
|
||||
Assert.IsFalse(Global.IsRegistered<AppConfig>());
|
||||
Assert.IsFalse(Global.IsRegistered<ILogger>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:获取已注册服务的数量
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Count_ReturnsCorrectNumber()
|
||||
{
|
||||
// Assert: 初始为 0
|
||||
Assert.AreEqual(0, Global.Count);
|
||||
|
||||
// Act: 注册服务
|
||||
Global.RegisterSingleton(new AppConfig());
|
||||
Assert.AreEqual(1, Global.Count);
|
||||
|
||||
Global.RegisterSingleton<ILogger>(new ConsoleLogger());
|
||||
Assert.AreEqual(2, Global.Count);
|
||||
|
||||
Global.RegisterTransient(() => new RequestContext());
|
||||
Assert.AreEqual(3, Global.Count);
|
||||
|
||||
// Act: 注销一个服务
|
||||
Global.Unregister<AppConfig>();
|
||||
Assert.AreEqual(2, Global.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 线程安全测试
|
||||
|
||||
/// <summary>
|
||||
/// 测试:多线程并发获取单例服务,确保只创建一次
|
||||
/// 演示容器的线程安全性
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Get_ConcurrentAccess_CreatesSingletonOnce()
|
||||
{
|
||||
// Arrange: 使用计数器追踪工厂方法调用次数
|
||||
var factoryCallCount = 0;
|
||||
var createdInstances = new HashSet<int>();
|
||||
|
||||
Global.RegisterSingleton(() =>
|
||||
{
|
||||
Interlocked.Increment(ref factoryCallCount);
|
||||
Thread.Sleep(50); // 模拟复杂初始化
|
||||
return new CacheService();
|
||||
});
|
||||
|
||||
// Act: 多线程并发获取
|
||||
var tasks = Enumerable.Range(0, 20).Select(i =>
|
||||
Task.Run(() =>
|
||||
{
|
||||
var service = Global.Get<CacheService>();
|
||||
lock (createdInstances)
|
||||
{
|
||||
createdInstances.Add(service.GetHashCode());
|
||||
}
|
||||
})
|
||||
).ToArray();
|
||||
|
||||
Task.WaitAll(tasks);
|
||||
|
||||
// Assert: 工厂方法只被调用一次,所有线程获取的是同一个实例
|
||||
Assert.AreEqual(1, factoryCallCount);
|
||||
Assert.AreEqual(1, createdInstances.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试:多线程并发订阅和更新
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Subscribe_ConcurrentSubscribeAndUpdate_ThreadSafe()
|
||||
{
|
||||
// Arrange: 注册服务
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "App", Version = "1.0" });
|
||||
|
||||
var notificationCounts = new System.Collections.Concurrent.ConcurrentBag<int>();
|
||||
|
||||
// Act: 多线程并发订阅
|
||||
var subscribeTasks = Enumerable.Range(0, 10).Select(i =>
|
||||
Task.Run(() =>
|
||||
{
|
||||
var count = 0;
|
||||
Global.Subscribe<AppConfig>(e => Interlocked.Increment(ref count));
|
||||
notificationCounts.Add(count);
|
||||
})
|
||||
).ToArray();
|
||||
|
||||
Task.WaitAll(subscribeTasks);
|
||||
|
||||
// Act: 触发更新
|
||||
Global.Update(new AppConfig { AppName = "App", Version = "2.0" });
|
||||
|
||||
// 等待所有通知处理完成
|
||||
Thread.Sleep(100);
|
||||
|
||||
// Assert: 不应该抛出异常,所有订阅者都应该收到通知
|
||||
Assert.AreEqual(10, notificationCounts.Count);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 实际应用场景测试
|
||||
|
||||
/// <summary>
|
||||
/// 场景测试:应用配置热更新
|
||||
/// 演示实时配置更新的完整流程
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Scenario_LiveConfigurationUpdate()
|
||||
{
|
||||
// Arrange: 模拟配置变更历史
|
||||
var configHistory = new List<string>();
|
||||
|
||||
// 订阅配置变更
|
||||
Global.Subscribe<AppConfig>(e =>
|
||||
{
|
||||
configHistory.Add($"v{e.OldValue?.Version} -> v{e.NewValue.Version}");
|
||||
});
|
||||
|
||||
// Act: 注册初始配置
|
||||
Global.RegisterSingleton(new AppConfig { AppName = "MyApp", Version = "1.0" });
|
||||
|
||||
// 模拟配置文件更新
|
||||
Global.Update(new AppConfig { AppName = "MyApp", Version = "1.1" });
|
||||
Global.Update(new AppConfig { AppName = "MyApp", Version = "1.2" });
|
||||
Global.Update(new AppConfig { AppName = "MyApp", Version = "2.0" });
|
||||
|
||||
// Assert: 应该记录所有变更
|
||||
Assert.AreEqual(3, configHistory.Count);
|
||||
Assert.AreEqual("v1.0 -> v1.1", configHistory[0]);
|
||||
Assert.AreEqual("v1.1 -> v1.2", configHistory[1]);
|
||||
Assert.AreEqual("v1.2 -> v2.0", configHistory[2]);
|
||||
|
||||
// 当前配置应该是最新的
|
||||
var currentConfig = Global.Get<AppConfig>();
|
||||
Assert.AreEqual("2.0", currentConfig.Version);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 场景测试:用户会话管理
|
||||
/// 演示多组件监听用户会话变更
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void Scenario_UserSessionManagement()
|
||||
{
|
||||
// Arrange: 模拟不同组件
|
||||
var uiUpdates = new List<string>();
|
||||
var logEntries = new List<string>();
|
||||
|
||||
// UI 组件订阅
|
||||
Global.Subscribe<UserSession>(e =>
|
||||
{
|
||||
uiUpdates.Add($"Display: {e.NewValue.Username}");
|
||||
});
|
||||
|
||||
// 日志组件订阅
|
||||
Global.Subscribe<UserSession>(e =>
|
||||
{
|
||||
logEntries.Add($"Session changed at {e.ChangedAt:HH:mm:ss}");
|
||||
});
|
||||
|
||||
// Act: 用户登录
|
||||
Global.RegisterSingleton(new UserSession
|
||||
{
|
||||
Username = "user1",
|
||||
LoginTime = DateTime.Now
|
||||
});
|
||||
|
||||
// 用户切换
|
||||
Thread.Sleep(10);
|
||||
Global.Update(new UserSession
|
||||
{
|
||||
Username = "user2",
|
||||
LoginTime = DateTime.Now
|
||||
});
|
||||
|
||||
// Assert: 各组件都应该收到通知
|
||||
Assert.AreEqual(1, uiUpdates.Count);
|
||||
Assert.AreEqual("Display: user2", uiUpdates[0]);
|
||||
Assert.AreEqual(1, logEntries.Count);
|
||||
Assert.IsTrue(logEntries[0].StartsWith("Session changed at"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 测试辅助类型
|
||||
|
||||
private class AppConfig
|
||||
{
|
||||
public string AppName { get; set; } = "";
|
||||
public string Version { get; set; } = "";
|
||||
}
|
||||
|
||||
private class RequestContext
|
||||
{
|
||||
public string RequestId { get; set; } = Guid.NewGuid().ToString();
|
||||
public DateTime Timestamp { get; set; } = DateTime.Now;
|
||||
}
|
||||
|
||||
private interface ILogger
|
||||
{
|
||||
void Log(string message);
|
||||
}
|
||||
|
||||
private class ConsoleLogger : ILogger
|
||||
{
|
||||
public void Log(string message) => Console.WriteLine($"[LOG] {message}");
|
||||
}
|
||||
|
||||
private class UserSession
|
||||
{
|
||||
public string Username { get; set; } = "";
|
||||
public DateTime LoginTime { get; set; }
|
||||
}
|
||||
|
||||
private class CacheService
|
||||
{
|
||||
private readonly Dictionary<string, object> _cache = new();
|
||||
}
|
||||
|
||||
private class OperationContext
|
||||
{
|
||||
public Guid OperationId { get; } = Guid.NewGuid();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
|
||||
Reference in new issue
Block a user