如何在Xunit测试项目中配置AutoFac依赖注入?
解决方案步骤
1. 允许测试项目访问Internal类型
由于Infrastructure层标记为internal,测试项目默认无法访问其内部成员。在Infrastructure层的项目文件(.csproj)中添加以下配置,授权测试项目访问:
<ItemGroup> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <_Parameter1>你的测试项目名称</_Parameter1> </AssemblyAttribute> </ItemGroup>
将你的测试项目名称替换为实际Xunit测试项目的名称(例如YourProject.Tests)。
2. 在测试项目中复用Autofac配置
把原项目的Autofac注册逻辑迁移到测试项目,构建可用于测试的容器。假设原项目的Autofac模块代码如下:
public class AutofacModule : Module { protected override void Load(ContainerBuilder builder) { // 注册Domain层服务 builder.RegisterAssemblyTypes(typeof(IDomainService).Assembly) .AsImplementedInterfaces() .InstancePerLifetimeScope(); // 注册Infrastructure层服务(已通过InternalsVisibleTo授权访问) builder.RegisterAssemblyTypes(typeof(IInfrastructureService).Assembly) .AsImplementedInterfaces() .InstancePerLifetimeScope(); // 注册Application层服务 builder.RegisterAssemblyTypes(typeof(UserService).Assembly) .AsImplementedInterfaces() .InstancePerLifetimeScope(); } }
在测试项目中创建容器初始化基类:
public class TestBase { protected IContainer Container { get; private set; } public TestBase() { var builder = new ContainerBuilder(); // 加载原项目的Autofac模块 builder.RegisterModule<AutofacModule>(); // 如需替换为Mock服务,可在此额外注册 // builder.RegisterInstance(new Mock<IInfrastructureService>().Object).As<IInfrastructureService>(); Container = builder.Build(); } }
3. 在Xunit测试类中注入依赖
让测试类继承TestBase,从容器中解析目标服务进行测试:
public class UserServiceTests : TestBase { private readonly IUserService _userService; public UserServiceTests() { _userService = Container.Resolve<IUserService>(); } [Fact] public void GetUserById_ShouldReturnValidUser() { var result = _userService.GetUserById(1); Assert.NotNull(result); } }
如果希望用构造注入简化代码,可以使用Xunit.DependencyInjection扩展:
- 安装NuGet包:
Install-Package Xunit.DependencyInjection - 在测试项目中创建Startup类配置Autofac:
public class Startup { public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterModule<AutofacModule>(); } }
- 测试类直接通过构造注入获取服务:
public class UserServiceTests { private readonly IUserService _userService; public UserServiceTests(IUserService userService) { _userService = userService; } [Fact] public void GetUserById_ShouldReturnValidUser() { var result = _userService.GetUserById(1); Assert.NotNull(result); } }
4. 常见问题排查
- 确认测试项目已引用Domain、Application、Infrastructure三层项目
- 检查
InternalsVisibleTo中的项目名称是否与测试项目完全一致(强命名项目需追加公钥) - 验证Autofac模块中的服务注册逻辑无遗漏或错误
内容的提问来源于stack exchange,提问作者Marcus Adams
相关产品推荐
相关产品推荐

