Dependency injection 如何在asp.net核心集成测试中测试数据库操作?

Dependency injection 如何在asp.net核心集成测试中测试数据库操作?,dependency-injection,asp.net-core,integration-testing,entity-framework-core,Dependency Injection,Asp.net Core,Integration Testing,Entity Framework Core,我正在尝试集成测试我的应用程序 例如,在我的AbController中,我有PostAb(AbDTO-AbDTO)方法,我想测试调用此方法是否会将AbDTO添加到db中 现在,我的测试设置: [SetUp] public void SetUp() { _server = new TestServer(new WebHostBuilder() .UseEnvironment("testing") .UseSta

我正在尝试集成测试我的应用程序

例如,在我的
AbController
中,我有
PostAb(AbDTO-AbDTO)
方法,我想测试调用此方法是否会将AbDTO添加到db中

现在,我的测试设置:

    [SetUp]
    public void SetUp()
    {
        _server = new TestServer(new WebHostBuilder()
            .UseEnvironment("testing")
            .UseStartup<Startup>());

        _client = _server.CreateClient();
    }
但是,如何将上下文注入测试?在我的应用程序中,我通过构造函数注入它,但在测试中我不能


谢谢

我假设您使用的是SqlLite,因此您可以像这样编辑您的安装方法:

[SetUp]
public void SetUp()
{
    _server = new TestServer(new WebHostBuilder()
        .UseEnvironment("testing")
        .UseStartup<Startup>());

    _client = _server.CreateClient();

    var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();

    optionsBuilder.UseSqlite("Filename=./blog.db");

    _context = new BloggingContext(optionsBuilder.Options);
}
[设置]
公共作废设置()
{
_服务器=新的TestServer(新的WebHostBuilder()
.UseEnvironment(“测试”)
.UseStartup());
_client=_server.CreateClient();
var optionsBuilder=new DbContextOptionsBuilder();
optionsBuilder.UseSqlite(“文件名=./blog.db”);
_context=newbloggingcontext(optionsBuilder.Options);
}

请告诉我这是否有用

我假设您使用的是SqlLite,因此您可以像下面这样编辑您的安装方法:

[SetUp]
public void SetUp()
{
    _server = new TestServer(new WebHostBuilder()
        .UseEnvironment("testing")
        .UseStartup<Startup>());

    _client = _server.CreateClient();

    var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();

    optionsBuilder.UseSqlite("Filename=./blog.db");

    _context = new BloggingContext(optionsBuilder.Options);
}
[设置]
公共作废设置()
{
_服务器=新的TestServer(新的WebHostBuilder()
.UseEnvironment(“测试”)
.UseStartup());
_client=_server.CreateClient();
var optionsBuilder=new DbContextOptionsBuilder();
optionsBuilder.UseSqlite(“文件名=./blog.db”);
_context=newbloggingcontext(optionsBuilder.Options);
}

请让我知道这是否有用

虽然我承认使用内存数据库进行集成测试是最彻底和安全的工作方式,但我的具体情况会使这方面非常困难和耗时。我使用的是一个托管的SQL开发服务器,经过一段时间的测试后我会覆盖它。我工作了几天,发现下面的过程给了我想要的结果

  • dotnetcore2.1
  • 需要测试数据中写入的业务逻辑的六边形(洋葱)体系结构 接入层
我添加的Program.CS文件:

//for integration testing
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(services => services.AddAutofac())
    .UseStartup<Startup>();
//用于集成测试
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(服务=>services.AddAutofac())
.UseStartup();
我的集成测试文件:

using Core.Data.Entities.Model;
using Core.Data.Entities.UTIA;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Profile.Data.Repos;
using Profile.Domain.DomainObjects;
using Super2.Web;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

namespace Profile.Test
{
    public class EmployeeProfileIntegrationTest : IClassFixture<WebApplicationFactory<Startup>>
    {
        private readonly HttpClient _client;

        public EmployeeProfileIntegrationTest(WebApplicationFactory<Startup> factory)
        {
            _client = factory.CreateClient();

        }

        private DBContext GetContext()
        {
            var options = new DbContextOptionsBuilder<DBContext>()
                .UseSqlServer("Server = 'Connection String from appsettings'")
                .Options;

            var context = new DBContext(options);
            return context;
        }



        [Fact]
        public async Task TestChildProtectionEmployeeGetData()
        {
            //Arrange
            var ApplicationUserId = XXXX;
            var repo = new EmployeeProfileRepo(GetContext());

            //ACT
            var sut = await repo.GetChildProtectionHistory(ApplicationUserId);

            //Assert
            var okResult = sut.Should().BeOfType<List<DomainObject>>().Subject;
            okResult.First().ApplicationUserId.Should().Be(XXXX);
        }
    }
}
使用Core.Data.Entities.Model;
使用Core.Data.Entities.UTIA;
使用FluentAssertions;
使用Microsoft.AspNetCore.Mvc.Testing;
使用Microsoft.EntityFrameworkCore;
使用Profile.Data.Repos;
使用Profile.Domain.DomainObjects;
使用Super2.Web;
使用System.Collections.Generic;
使用System.Linq;
使用System.Net.Http;
使用System.Threading.Tasks;
使用Xunit;
名称空间配置文件.Test
{
公共类EmployeeProfileIntegrationTest:IClassFixture
{
私有只读HttpClient\u客户端;
公共雇员专业集成测试(WebApplicationFactory)
{
_client=factory.CreateClient();
}
私有DBContext GetContext()
{
var options=new DbContextOptionsBuilder()
.UseSqlServer(“服务器='来自appsettings的连接字符串'”)
.选择;
var context=新的DBContext(选项);
返回上下文;
}
[事实]
公共异步任务TestChildProtectionEmployeeGetData()
{
//安排
var applicationserid=XXXX;
var repo=新员工ePerofileRepo(GetContext());
//表演
var sut=等待回购GetChildProtectionHistory(ApplicationSerID);
//断言
var okResult=sut.Should().BeOfType().Subject;
okResult.First().ApplicationUserId.Should()为(XXXX);
}
}
}
当我将我的上下文注入到另一个层中时,我会怀疑它对控制器的作用是相同的。我包含了启动代码段,因为这给我带来了一些问题,因为testserver正在寻找IWebHostBuilder,而不是默认的Core2.1 IWebHost


不管怎样,这对我来说都有效。希望你能从中得到一些帮助

虽然我承认使用内存数据库进行集成测试是最彻底、最安全的工作方式,但我的具体情况会使这方面变得非常困难和耗时。我使用的是一个托管的SQL开发服务器,经过一段时间的测试后我会覆盖它。我工作了几天,发现下面的过程给了我想要的结果

  • dotnetcore2.1
  • 需要测试数据中写入的业务逻辑的六边形(洋葱)体系结构 接入层
我添加的Program.CS文件:

//for integration testing
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(services => services.AddAutofac())
    .UseStartup<Startup>();
//用于集成测试
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(服务=>services.AddAutofac())
.UseStartup();
我的集成测试文件:

using Core.Data.Entities.Model;
using Core.Data.Entities.UTIA;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Profile.Data.Repos;
using Profile.Domain.DomainObjects;
using Super2.Web;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;

namespace Profile.Test
{
    public class EmployeeProfileIntegrationTest : IClassFixture<WebApplicationFactory<Startup>>
    {
        private readonly HttpClient _client;

        public EmployeeProfileIntegrationTest(WebApplicationFactory<Startup> factory)
        {
            _client = factory.CreateClient();

        }

        private DBContext GetContext()
        {
            var options = new DbContextOptionsBuilder<DBContext>()
                .UseSqlServer("Server = 'Connection String from appsettings'")
                .Options;

            var context = new DBContext(options);
            return context;
        }



        [Fact]
        public async Task TestChildProtectionEmployeeGetData()
        {
            //Arrange
            var ApplicationUserId = XXXX;
            var repo = new EmployeeProfileRepo(GetContext());

            //ACT
            var sut = await repo.GetChildProtectionHistory(ApplicationUserId);

            //Assert
            var okResult = sut.Should().BeOfType<List<DomainObject>>().Subject;
            okResult.First().ApplicationUserId.Should().Be(XXXX);
        }
    }
}
使用Core.Data.Entities.Model;
使用Core.Data.Entities.UTIA;
使用FluentAssertions;
使用Microsoft.AspNetCore.Mvc.Testing;
使用Microsoft.EntityFrameworkCore;
使用Profile.Data.Repos;
使用Profile.Domain.DomainObjects;
使用Super2.Web;
使用System.Collections.Generic;
使用System.Linq;
使用System.Net.Http;
使用System.Threading.Tasks;
使用Xunit;
名称空间配置文件.Test
{
公共类EmployeeProfileIntegrationTest:IClassFixture
{
私有只读HttpClient\u客户端;
公共雇员专业集成测试(WebApplicationFactory)
{
_client=factory.CreateClient();
}
私有DBContext GetContext()
{
var options=new DbContextOptionsBuilder()
.UseSqlServer(“服务器='来自appsettings的连接字符串'”)
.选择;
var context=新的DBContext(选项);
返回上下文;
}
[事实]
公共异步任务TestChildProtectionEmployeeGetData()
{
//安排
var applicationserid=XXXX;
var-re