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

Posted

技术标签:

【中文标题】.NET Core 的 NUnit Entity Framework 集成测试依赖注入问题【英文标题】:NUnit Entity Framework integration test dependency injection issue with .NET Core 【发布时间】:2018-08-27 07:23:45 【问题描述】:

我刚刚开始研究带有实体框架的 .NET Core。我以前使用过 .NET Framework 和 Ninject,但我现在尝试使用 .NET Core 中内置的 DI。

我有一个 TestBase 类,我的测试将从中派生。我希望这个类负责使用[OneTimeSetUp][OneTimeTearDown] 创建和删除测试数据库。问题是我似乎无法弄清楚如何在设置和拆卸方法中访问我的 DI 服务。这些方法不能有参数,我的TestBase 类必须有一个无参数的构造函数,所以我也不能从那里得到它们。

[SetUpFixture]
public partial class TestBase

    protected IEFDatabaseContext DataContext  get; set; 

    public TestBase(IEFDatabaseContext dataContext)
    
        this.DataContext = dataContext;
    

    [OneTimeSetUp]
    public void TestInitialise()
    
        this.DataContext.Database.EnsureCreated();
    

    [OneTimeTearDown]
    public void TestTearDown()
    
        this.DataContext.Database.EnsureDeleted();
    

上面给出了以下错误:

TestBase 没有默认构造函数。

我可能会以错误的方式解决这个问题,但这是我过去一直做的事情,所以请告诉我在使用 .NET Core DI 时是否有更好的方法。


Startup类供参考:

public class Startup

    private readonly IConfiguration config;

    public Startup(IConfiguration config)
    
        this.config = config;
    

    public void ConfigureServices(IServiceCollection services)
    
        services.AddDbContext<TestDataContext>(
            options => options.UseSqlServer(this.config.GetConnectionString("TestConnectionString")),
            ServiceLifetime.Singleton);

        services.AddScoped<IEFDatabaseContext>(provider => provider.GetService<TestDataContext>());
    

【问题讨论】:

Reconfigure dependencies when Integration testing ASP.NET Core Web API and EF Core的可能重复 感谢@NightOwl888,您帮我找到了我刚刚发布的解决方案。 【参考方案1】:

感谢 NightOwl 为我指明了正确的方向。结合 Microsoft article on integration testing 和可能的欺骗问题,我得出了以下解决方案。

通过使用Microsoft.AspNetCore.TestHost 中的TestServer,我可以访问Startup 中内置的DI ServiceProvider

测试库:

public partial class TestBase

    protected readonly TestServer server;
    protected readonly IEFDatabaseContext DataContext;

    public TestBase()
    
        this.server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
        this.DataContext = this.server.Host.Services.GetService<IEFDatabaseContext>();
    

    [OneTimeSetUp]
    public void TestInitialise()
    
        this.DataContext.Database.EnsureCreated();
    

    [OneTimeTearDown]
    public void TestTearDown()
    
        this.DataContext.Database.EnsureDeleted();
    

启动:

public class Startup

    private readonly IConfiguration config;

    public Startup(IConfiguration config)
    
        this.config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();
    

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    

    

    public void ConfigureServices(IServiceCollection services)
    
        services.AddDbContext<TestDataContext>(
            options => options.UseSqlServer(this.config.GetConnectionString("TestConnectionString")),
            ServiceLifetime.Singleton);

        services.AddScoped<IEFDatabaseContext>(provider => provider.GetService<TestDataContext>());
    

【讨论】:

【参考方案2】:

Integration testing ASP.NET Core 在 Microsoft 文档中得到了很好的介绍。

基本上,您需要从 NuGet Microsoft.AspNetCore.TestHost 安装 Test Host 项目,然后使用它在 NUnit 中启动 Web 环境。

基本示例

public class TestClass

    private TestServer _server;
    private HttpClient _client;

    [OneTimeSetUp]
    public void SetUp()
    
        // Arrange
        _server = new TestServer(new WebHostBuilder()
            .UseStartup<Startup>());
        _client = _server.CreateClient();
    

    [OneTimeTearDown]
    public void TearDown()
    
        _server = null;
        _client = null;
    

    [Test]
    public async Task ReturnHelloWorld()
    
        // Act
        var response = await _client.GetAsync("/");
        response.EnsureSuccessStatusCode();

        var responseString = await response.Content.ReadAsStringAsync();

        // Assert
        Assert.Equal("Hello World!",
            responseString);
    

使用TestServer 可以干预DI 配置和/或IConfiguration 以替换配置中的假货。见Reconfigure dependencies when Integration testing ASP.NET Core Web API and EF Core。

【讨论】:

以上是关于.NET Core 的 NUnit Entity Framework 集成测试依赖注入问题的主要内容,如果未能解决你的问题,请参考以下文章

在 .NET Core 控制台应用程序中使用带有 NUnit3 的 app.config 文件

C# - 单元测试 - 初始化私有字段 - ASP.NET Core 5 - NUnit 测试

如何在 Bamboo 中运行 .NET Core 单元测试?

Entity Framework Core/.NET Core 不会始终如一地返回结果

根据 ASP.NET Core 和 Entity Framework Core 中的条件禁用 [必需] 属性

Entity Framework Core 添加到 .Net Core Web Api - IRelationalTypeMappingSource 问题