.NET Core 2.0单元测试项目中如何通过Startup类实现依赖注入
解决.NET Core 2.0 MS Test项目中依赖注入与Startup使用问题
MS Test框架确实强制要求测试类必须有无参构造函数,所以直接通过构造函数注入依赖的路子走不通。不过我们可以手动在测试类里搭建依赖注入容器,复用你的Startup类来配置服务,同时加载appsettings.json配置。下面是具体的实现步骤和代码示例:
第一步:确保配置文件能被测试项目读取
右键你的测试项目中的appsettings.json文件 → 选择「属性」,将「复制到输出目录」设置为始终复制或如果较新则复制,这样测试运行时才能找到配置文件。
第二步:修改测试类,手动初始化DI容器
我们会在TestInitialize方法里完成配置加载、服务容器构建、依赖实例获取的工作,同时处理数据库事务来避免测试污染真实数据:
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.IO; [TestClass] public class TestHelpers { private MyDataContext _context; private UnitOfWork _uow; private IDbContextTransaction _transaction; private IServiceProvider _serviceProvider; // 无参构造函数,满足MS Test的强制要求 public TestHelpers() { } [TestInitialize] public void Init() { // 1. 加载appsettings.json配置 var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); // 2. 初始化服务容器并复用Startup的配置逻辑 var services = new ServiceCollection(); var startup = new Startup(config); startup.ConfigureServices(services); // 可选:如果希望通过DI获取UnitOfWork,可在Startup的ConfigureServices中添加注册 // services.AddScoped<IUnitOfWork, UnitOfWork>(); // 3. 构建服务提供器 _serviceProvider = services.BuildServiceProvider(); // 4. 从容器中获取所需依赖实例 _context = _serviceProvider.GetRequiredService<MyDataContext>(); // 如果注册了IUnitOfWork,就用下面的方式获取,不用手动new // _uow = _serviceProvider.GetRequiredService<IUnitOfWork>(); _uow = new UnitOfWork(_context); // 5. 开启数据库事务,测试完成后回滚 _transaction = _context.Database.BeginTransaction(); } [TestCleanup] public void Cleanup() { // 回滚事务,避免测试数据污染数据库 _transaction.Rollback(); // 释放资源 _transaction.Dispose(); _context.Dispose(); (_serviceProvider as IDisposable)?.Dispose(); } // 示例测试方法 [TestMethod] public void TestDataInsertion() { // 使用_uow或_context执行测试逻辑 // 比如:_uow.SomeRepository.Add(new Entity()); // _uow.SaveChanges(); // 断言验证结果 // Assert.IsNotNull(...); } }
额外注意事项
- 如果你还没安装
Microsoft.EntityFrameworkCore.SqlServer包,需要补上,因为UseSqlServer方法依赖这个包。 - 如果是纯单元测试场景,更推荐使用EF Core的内存数据库(
UseInMemoryDatabase),避免依赖真实数据库,提升测试速度。 - 若项目中有更多依赖(比如其他服务类),都可以在
Startup的ConfigureServices里注册,然后通过_serviceProvider.GetRequiredService<T>()获取实例,保持DI的一致性。
内容的提问来源于stack exchange,提问作者Pinpoint Solutions
相关产品推荐
相关产品推荐

