using Microsoft.VisualStudio.TestTools.UnitTesting; namespace NavisworksTransport.UnitTests { /// /// ThreadSafeObservableCollection基础功能测试 /// 只包含可以在控制台环境下稳定运行的纯数据操作测试,不涉及事件 /// [TestClass] public class ThreadSafeObservableCollectionBasicTests { private ThreadSafeObservableCollection _collection; [TestInitialize] public void Setup() { _collection = new ThreadSafeObservableCollection(); } [TestCleanup] public void Cleanup() { _collection = null; } #region 构造函数测试 [TestMethod] public void Constructor_ShouldCreateEmptyCollection() { // Arrange & Act var collection = new ThreadSafeObservableCollection(); // Assert Assert.AreEqual(0, collection.Count, "新创建的集合应该为空"); } [TestMethod] public void Constructor_WithInitialItems_ShouldContainAllItems() { // Arrange var initialItems = new[] { "A", "B", "C" }; // Act var collection = new ThreadSafeObservableCollection(initialItems); // Assert Assert.AreEqual(3, collection.Count, "集合应该包含所有初始元素"); var snapshot = collection.ToSnapshot(); CollectionAssert.AreEqual(initialItems, snapshot, "集合内容应该与初始元素相同"); } #endregion #region 基础数据操作测试 [TestMethod] public void Add_ShouldIncreaseCount() { // Arrange var item = "TestItem"; // Act _collection.Add(item); // Assert Assert.AreEqual(1, _collection.Count, "添加元素后集合计数应该增加"); Assert.IsTrue(_collection.Contains(item), "集合应该包含添加的元素"); } [TestMethod] public void Remove_ShouldDecreaseCount() { // Arrange var item = "TestItem"; _collection.Add(item); // Act var result = _collection.Remove(item); // Assert Assert.IsTrue(result, "移除已存在的元素应该返回true"); Assert.AreEqual(0, _collection.Count, "移除元素后集合计数应该减少"); Assert.IsFalse(_collection.Contains(item), "集合不应该包含已移除的元素"); } [TestMethod] public void Insert_ShouldInsertAtCorrectPosition() { // Arrange _collection.Add("A"); _collection.Add("C"); // Act _collection.Insert(1, "B"); // Assert Assert.AreEqual(3, _collection.Count, "插入元素后集合计数应该增加"); Assert.AreEqual("B", _collection[1], "元素应该被插入到正确位置"); var snapshot = _collection.ToSnapshot(); CollectionAssert.AreEqual(new[] { "A", "B", "C" }, snapshot, "集合顺序应该正确"); } [TestMethod] public void Clear_ShouldRemoveAllItems() { // Arrange _collection.Add("A"); _collection.Add("B"); _collection.Add("C"); // Act _collection.Clear(); // Assert Assert.AreEqual(0, _collection.Count, "清空后集合应该为空"); } #endregion #region 批量操作测试 [TestMethod] public void AddRange_ShouldAddAllItems() { // Arrange var items = new[] { "A", "B", "C" }; // Act _collection.AddRange(items); // Assert Assert.AreEqual(3, _collection.Count, "AddRange应该添加所有元素"); var snapshot = _collection.ToSnapshot(); CollectionAssert.AreEqual(items, snapshot, "集合内容应该与添加的元素相同"); } [TestMethod] public void AddRange_WithEmptyCollection_ShouldNotChangeCount() { // Arrange var emptyItems = new string[0]; // Act _collection.AddRange(emptyItems); // Assert Assert.AreEqual(0, _collection.Count, "添加空集合不应该改变计数"); } [TestMethod] public void RemoveRange_ShouldRemoveMatchingItems() { // Arrange _collection.AddRange(new[] { "A", "B", "C", "D" }); var itemsToRemove = new[] { "B", "D" }; // Act var removedCount = _collection.RemoveRange(itemsToRemove); // Assert Assert.AreEqual(2, removedCount, "应该移除2个元素"); Assert.AreEqual(2, _collection.Count, "移除后集合应该包含2个元素"); var snapshot = _collection.ToSnapshot(); CollectionAssert.AreEqual(new[] { "A", "C" }, snapshot, "剩余元素应该正确"); } [TestMethod] public void ClearAndAddRange_ShouldReplaceAllItems() { // Arrange _collection.AddRange(new[] { "Old1", "Old2" }); var newItems = new[] { "New1", "New2", "New3" }; // Act _collection.ClearAndAddRange(newItems); // Assert Assert.AreEqual(3, _collection.Count, "替换后集合应该包含新元素的数量"); var snapshot = _collection.ToSnapshot(); CollectionAssert.AreEqual(newItems, snapshot, "集合内容应该是新元素"); } #endregion #region 查询操作测试 [TestMethod] public void FirstOrDefault_ShouldReturnCorrectItem() { // Arrange _collection.AddRange(new[] { "Apple", "Banana", "Cherry" }); // Act var result = _collection.FirstOrDefault(item => item.StartsWith("B")); // Assert Assert.AreEqual("Banana", result, "FirstOrDefault应该返回第一个匹配的元素"); } [TestMethod] public void Count_WithPredicate_ShouldReturnCorrectCount() { // Arrange _collection.AddRange(new[] { "Apple", "Banana", "Apricot", "Cherry" }); // Act var count = _collection.Count(item => item.StartsWith("A")); // Assert Assert.AreEqual(2, count, "Count应该返回满足条件的元素数量"); } [TestMethod] public void Any_WithPredicate_ShouldReturnCorrectResult() { // Arrange _collection.AddRange(new[] { "Apple", "Banana", "Cherry" }); // Act var hasZ = _collection.Any(item => item.StartsWith("Z")); var hasA = _collection.Any(item => item.StartsWith("A")); // Assert Assert.IsFalse(hasZ, "不存在以Z开头的元素时Any应该返回false"); Assert.IsTrue(hasA, "存在以A开头的元素时Any应该返回true"); } [TestMethod] public void ToSnapshot_ShouldReturnCurrentState() { // Arrange _collection.AddRange(new[] { "A", "B", "C" }); // Act var snapshot1 = _collection.ToSnapshot(); _collection.Add("D"); var snapshot2 = _collection.ToSnapshot(); // Assert CollectionAssert.AreEqual(new[] { "A", "B", "C" }, snapshot1, "第一个快照应该不包含后添加的元素"); CollectionAssert.AreEqual(new[] { "A", "B", "C", "D" }, snapshot2, "第二个快照应该包含后添加的元素"); } #endregion #region 异常处理测试 [TestMethod] public void Add_WithNull_ShouldThrowArgumentNullException() { // Act & Assert Assert.ThrowsException(() => { _collection.Add(null); }, "添加null元素应该抛出ArgumentNullException"); } [TestMethod] public void AddRange_WithNull_ShouldThrowArgumentNullException() { // Act & Assert Assert.ThrowsException(() => { _collection.AddRange(null); }, "AddRange传入null应该抛出ArgumentNullException"); } [TestMethod] public void IndexAccess_WithInvalidIndex_ShouldThrowArgumentOutOfRangeException() { // Arrange _collection.Add("OnlyItem"); // Act & Assert Assert.ThrowsException(() => { var item = _collection[5]; // 无效索引 }, "访问无效索引应该抛出ArgumentOutOfRangeException"); } #endregion } }