为何被Mock的集合类在被测方法中无法正常填充元素?
解决Mock集合对象Add方法不生效的问题
默认情况下,Moq创建的mock对象只会执行你手动Setup的方法逻辑,其他未配置的方法/属性都会返回默认值(比如Count返回0),也不会执行实际的基类方法。所以调用Add时,mock对象并没有真正执行添加元素的逻辑,自然Count不会更新。
以下是两种可行的解决方法:
方案1:启用CallBase调用基类实际逻辑
如果只需要替换ApplyEdits方法,其他集合操作(比如Add、Count)希望保留基类的实际行为,可以在创建Mock时设置CallBase = true:
[TestMethod] public void MyTest() { // 开启CallBase,让未Mock的方法调用基类的真实实现 var mock = new Mock<MyCollectionClass>() { CallBase = true }; // 仅替换ApplyEdits方法的返回值 mock.Setup(m => m.ApplyEdits()).Returns("dummy"); var classToBeTested = new ClassToBeTested(); var items = new List<string> { "test1", "test2", "test3" }; var result = classToBeTested.MethodToBeTested(mock.Object, items.ToArray()); Assert.AreEqual(items.Count, result); }
这种方式最简单,适合大部分场景,它保留了Collection<T>基类的所有集合操作逻辑,只替换你需要隔离的ApplyEdits方法。
方案2:手动模拟Add和Count的行为
如果不想依赖基类的实现,希望完全控制集合的行为,可以手动维护一个内部列表,模拟Add和Count的逻辑:
[TestMethod] public void MyTest() { // 用真实列表模拟集合的内部存储 var internalStorage = new List<MyClass>(); var mock = new Mock<MyCollectionClass>(); // 配置Add方法,将元素添加到内部列表 mock.Setup(m => m.Add(It.IsAny<MyClass>())) .Callback<MyClass>(item => internalStorage.Add(item)); // 配置Count属性,返回内部列表的元素数量 mock.SetupGet(m => m.Count) .Returns(() => internalStorage.Count); // 替换ApplyEdits方法 mock.Setup(m => m.ApplyEdits()).Returns("dummy"); var classToBeTested = new ClassToBeTested(); var items = new List<string> { "test1", "test2", "test3" }; var result = classToBeTested.MethodToBeTested(mock.Object, items.ToArray()); Assert.AreEqual(items.Count, result); }
这种方式更灵活,适合需要自定义集合行为的测试场景。
内容的提问来源于stack exchange,提问作者awe
相关产品推荐
相关产品推荐

