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

And*_*iss 5 c# integration-testing entity-framework dependency-injection asp.net-core

我刚刚开始研究带有实体框架的.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();
    }
}
Run Code Online (Sandbox Code Playgroud)

上面给出了以下错误:

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>());
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*iss 5

感谢 NightOwl 为我指明了正确的方向。Microsoft关于集成测试的文章和可能的欺骗问题的结合使我找到了以下解决方案。

通过使用TestServerfromMicrosoft.AspNetCore.TestHost我可以访问ServiceProvider内置的 DI Startup

测试基地:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

启动:

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>());
    }
}
Run Code Online (Sandbox Code Playgroud)


Nig*_*888 3

Microsoft 文档详细介绍了ASP.NET Core 的集成测试。

基本上,您需要从 NuGet安装测试主机Microsoft.AspNetCore.TestHost项目,然后使用它在 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

有了它TestServer,就可以干预 DI 配置和/或IConfiguration替换配置中的赝品。请参阅集成测试 ASP.NET Core Web API 和 EF Core 时重新配置依赖项