如何让C#单元测试Stub与Shim适配抽象类?Fake类缺失问题排查
问题分析与解决方案
一、抽象类Stub伪造的可行性
首先明确:抽象类的抽象方法完全可以通过Stub来伪造返回值。不过要注意,微软Azure Cosmos DB SDK里的Container是具体类,如果你要测试依赖它的代码,更建议先封装一层抽象接口(比如ICosmosContainer),把GetItemLinqQueryable方法定义在接口里,让业务代码依赖这个接口而非具体的Container类——这样后续用Stub伪造会更顺畅。
要实现让GetItemLinqQueryable返回伪造查询,核心步骤是:
- 定义抽象接口/类,包含目标方法;
- 业务代码依赖抽象层;
- 测试时用Stub生成抽象层的实例,重写
GetItemLinqQueryable返回预先准备好的内存集合(比如new List<YourModel>().AsQueryable())。
二、Fakes命名空间找不到自定义类的原因及解决
你在WebApplication1.Controllers下定义的NonStaticClass在Fakes里找不到,主要是这几个原因:
1. 未正确生成Fakes程序集
右键点击测试项目中引用的、包含NonStaticClass的项目,选择添加Fakes程序集,等待VS自动生成对应的Fakes命名空间(比如WebApplication1.Controllers.Fakes)。如果生成失败,去输出窗口看具体错误,比如原项目是否有编译问题导致Fakes无法生成。
2. MSTest 3.x的Fakes依赖问题
MSTest 3.x不再默认集成Fakes,需要手动安装NuGet包:
- 安装
Microsoft.QualityTools.Testing.Fakes(旧版Fakes,和教程匹配度高); - 确保测试项目的
.csproj里正确引用了这个包,否则Fakes程序集无法正常生成。
3. 访问修饰符或命名空间问题
- 必须确保
NonStaticClass是public修饰的,Fakes只能为public类型生成Stub/Shim; - 测试代码里要手动导入Fakes命名空间:
using WebApplication1.Controllers.Fakes;,否则IDE会提示找不到类。
三、官方教程中Fakes的核心用法
官方教程里的Stub逻辑其实很简单:
- 先给目标类所在的项目生成Fakes程序集;
- 在测试代码中,通过
Stub[原类名]创建实例,重写抽象/虚方法:
// 示例:假设你的抽象类是public abstract class CosmosContainerBase var stubContainer = new StubCosmosContainerBase(); stubContainer.GetItemLinqQueryableOfTItem = () => { // 返回伪造的查询结果 var fakeData = new List<YourModel> { new YourModel { Id = "test" } }; return fakeData.AsQueryable(); };
- 把这个Stub实例注入到被测试的业务代码里,替换真实的Container实例即可。
另外要区分Stub和Shim:Stub适合抽象类、接口、虚方法的伪造(基于继承实现),Shim则多用于静态类、密封类、非虚方法的篡改,你的场景用Stub就足够了。
四、版本问题的确认
MSTest 3.11本身支持Fakes,但要注意:
- 必须手动安装对应的Fakes NuGet包,不能依赖旧版MSTest的默认集成;
- 建议搭配VS2022使用,旧版VS对MSTest 3.x和Fakes的兼容性较差;
- 如果之前用的是MSTest 2.x,升级后要检查Fakes的配置是否有冲突,比如移除旧的引用,重新安装新版包。
内容的提问来源于stack exchange,提问作者Tanny Xie
相关产品推荐
相关产品推荐

