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

时间:2016-12-08 23:02:59

标签: 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")
            .UseStartup<Startup>());

        _client = _server.CreateClient();
    }

我的测试应该是这样的:

    [Test]
    public async Task PostAbSanity()
    {
        await _client.PostAsync("/rest/v1/Ab", new Ab{Id=1});
        _context.Abs.find(1).should().NotBeNull();
    }

但是,如何将_context注入测试?在我的应用程序中,我通过构造函数注入它,但在测试中我不能。

谢谢!

2 个答案:

答案 0 :(得分:1)

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

[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);
}

请告诉我这是否有用

答案 1 :(得分:1)

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

  • DotNet Core 2.1
  • 六角形(洋葱形)体系结构需要测试写入我的数据中的业务逻辑 接入层

我添加的Program.CS文件:

//for integration testing
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
    .ConfigureServices(services => services.AddAutofac())
    .UseStartup<Startup>();

我的集成测试文件:

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);
        }
    }
}

当我将上下文注入到不同的层时,我会怀疑它对于控制器的作用是否相同。我包括了启动片段,因为这导致我遇到了一些问题,因为测试服务器正在寻找IWebHostBuilder而不是默认的Core2.1 IWebHost。

无论哪种方式,这都对我有用。希望您能从中得到一些帮助。