You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core下NUnit与Entity Framework集成测试依赖注入问题

嘿,这个问题我之前帮同事解决过,刚好能给你捋清楚怎么弄!

首先,咱们得明白:.NET Core的内置DI不会自动在测试项目里初始化,不像ASP.NET Core项目那样有现成的容器。所以咱们得在TestBase里手动搭建DI容器,这样才能在[OneTimeSetUp]和[OneTimeTearDown]里拿到需要的服务(比如你的EF Core DbContext)。

下面是具体的实现步骤和代码示例:

1. 在TestBase中构建DI容器

咱们要在[OneTimeSetUp]方法里初始化服务集合,注册所有需要的服务(包括DbContext和业务服务),然后构建ServiceProvider。

2. 借助Scope获取Scoped服务

EF Core的DbContext默认是Scoped生命周期的,所以不能直接从ServiceProvider获取,得创建一个服务范围(Scope)来获取,避免生命周期管理问题。

完整的TestBase示例代码

using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using NUnit.Framework;

public class TestBase
{
    protected IServiceProvider ServiceProvider { get; private set; }

    [OneTimeSetUp]
    public void GlobalTestSetup()
    {
        // 1. 初始化服务集合
        var services = new ServiceCollection();

        // 2. 注册EF Core DbContext(这里用SQL Server举例,也可以换成内存数据库)
        services.AddDbContext<YourTestDbContext>(options =>
            options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=YourTestDb;Trusted_Connection=True;"));

        // 3. 注册其他你需要的服务(比如业务逻辑服务)
        services.AddScoped<IYourBusinessService, YourBusinessService>();

        // 4. 构建服务提供器
        ServiceProvider = services.BuildServiceProvider();

        // 5. 创建测试数据库并初始化
        using var scope = ServiceProvider.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<YourTestDbContext>();
        dbContext.Database.EnsureCreated(); // 自动创建数据库和表
    }

    [OneTimeTearDown]
    public void GlobalTestTeardown()
    {
        // 1. 删除测试数据库
        using var scope = ServiceProvider.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<YourTestDbContext>();
        dbContext.Database.EnsureDeleted(); // 彻底删除数据库

        // 2. 释放服务提供器资源
        if (ServiceProvider is IDisposable disposableProvider)
        {
            disposableProvider.Dispose();
        }
    }
}

几个关键注意点:

  • 内存数据库选项:如果不想用真实的SQL Server,也可以换成内存数据库,只需要把UseSqlServer换成UseInMemoryDatabase("YourTestDb"),但要注意内存数据库在不同Scope里的隔离性,根据你的测试需求调整。
  • 服务生命周期:对于Scoped和Transient服务,一定要通过CreateScope()获取,用完后Scope会自动释放资源;Singleton服务可以直接从ServiceProvider获取。
  • 测试类继承:你的测试类只需要继承这个TestBase,就能自动执行数据库的创建和清理,而且在测试方法里也可以通过ServiceProvider.CreateScope()获取需要的服务。

这样就能解决你在[OneTimeSetUp]和[OneTimeTearDown]里无法访问DI服务的问题啦!

内容的提问来源于stack exchange,提问作者Andy Furniss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:36:55