【问题标题】:NUnit Entity Framework integration test dependency injection issue with .NET Core.NET Core 的 NUnit Entity Framework 集成测试依赖注入问题
【发布时间】: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>());
    }
}

【问题讨论】:

标签: c# entity-framework asp.net-core dependency-injection integration-testing


【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 2016-05-22
      相关资源
      最近更新 更多