NavisworksTransport/UnitTests/Collections/ThreadSafeObservableCollectionBasicTests.cs

284 lines
8.8 KiB
C#

using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace NavisworksTransport.UnitTests
{
/// <summary>
/// ThreadSafeObservableCollection基础功能测试
/// 只包含可以在控制台环境下稳定运行的纯数据操作测试,不涉及事件
/// </summary>
[TestClass]
public class ThreadSafeObservableCollectionBasicTests
{
private ThreadSafeObservableCollection<string> _collection;
[TestInitialize]
public void Setup()
{
_collection = new ThreadSafeObservableCollection<string>();
}
[TestCleanup]
public void Cleanup()
{
_collection = null;
}
#region
[TestMethod]
public void Constructor_ShouldCreateEmptyCollection()
{
// Arrange & Act
var collection = new ThreadSafeObservableCollection<int>();
// Assert
Assert.AreEqual(0, collection.Count, "新创建的集合应该为空");
}
[TestMethod]
public void Constructor_WithInitialItems_ShouldContainAllItems()
{
// Arrange
var initialItems = new[] { "A", "B", "C" };
// Act
var collection = new ThreadSafeObservableCollection<string>(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<ArgumentNullException>(() =>
{
_collection.Add(null);
}, "添加null元素应该抛出ArgumentNullException");
}
[TestMethod]
public void AddRange_WithNull_ShouldThrowArgumentNullException()
{
// Act & Assert
Assert.ThrowsException<ArgumentNullException>(() =>
{
_collection.AddRange(null);
}, "AddRange传入null应该抛出ArgumentNullException");
}
[TestMethod]
public void IndexAccess_WithInvalidIndex_ShouldThrowArgumentOutOfRangeException()
{
// Arrange
_collection.Add("OnlyItem");
// Act & Assert
Assert.ThrowsException<ArgumentOutOfRangeException>(() =>
{
var item = _collection[5]; // 无效索引
}, "访问无效索引应该抛出ArgumentOutOfRangeException");
}
#endregion
}
}