为何应用会调用带IServiceProvider的构造函数?如何仅在单元测试中启用
解决测试专用构造函数仅在单元测试项目生效的问题
方案1:使用条件编译指令
通过定义单元测试专属的编译符号,让测试构造函数仅在测试项目中被编译。
修改你的Repo类代码:
public class Repo : BaseRepo { public Repo() : base() { } #if UNIT_TEST // 仅在定义了UNIT_TEST符号的项目中生效 public Repo(IServiceProvider serviceProvider) : base(serviceProvider) { } #endif }
设置步骤:
- 打开单元测试项目的属性窗口,切换到「生成」标签页
- 在「条件编译符号」输入框中添加
UNIT_TEST(多个符号用分号分隔) - 主项目不要添加这个符号,这样主项目编译时会自动忽略这个构造函数
方案2:使用internal修饰符+InternalsVisibleTo特性
将测试构造函数设为internal,然后允许单元测试项目访问主项目的内部成员。
修改Repo类:
public class Repo : BaseRepo { public Repo() : base() { } // internal修饰符限制仅同程序集或授权程序集可访问 internal Repo(IServiceProvider serviceProvider) : base(serviceProvider) { } }
然后在主项目的AssemblyInfo.cs文件中添加授权(如果没有AssemblyInfo.cs,可以直接在项目的任意.cs文件顶部添加):
[assembly: InternalsVisibleTo("YourUnitTestProjectName")]
替换YourUnitTestProjectName为你的单元测试项目的程序集名称(无强命名直接写项目名称即可,有强命名需额外添加公钥)。
这样主项目外的其他项目无法看到这个internal构造函数,但单元测试项目可以正常调用。
方案3:创建测试专用子类
在单元测试项目中创建继承自Repo的子类,专门用于测试场景,完全避免在主项目中留下测试相关代码。
主项目中的Repo保持不变:
public class Repo : BaseRepo { public Repo() : base() { } }
单元测试项目中添加TestRepo:
public class TestRepo : Repo { public TestRepo(IServiceProvider serviceProvider) : base() { // 若BaseRepo允许通过属性/方法设置服务提供者,在此注入Mock实例 // 若BaseRepo有protected带参构造函数,可改为: base(serviceProvider) } }
单元测试中直接使用TestRepo注入Mock的IServiceProvider即可。
你之前符号尝试无效的可能原因
大概率是未在单元测试项目中正确设置编译符号,或者符号名称与代码中的#if指令大小写、拼写不匹配,检查二者是否完全一致即可。
内容的提问来源于stack exchange,提问作者karthik N
相关产品推荐
相关产品推荐

