集成测试始终返回500状态代码

时间:2020-03-10 13:10:48

标签: c# asp.net-core entity-framework-core

我正在构建我的第一个系统,并试图维护测试等良好实践。

现在,我的集成测试设置面临问题。我只是跟随 Microsoft 的框架进行了一些改动,以使用SQL Lite InMemory db。

运行测试时,我只会得到using PMES.HelpDesk.Teste.IntegrationTests.Factory; using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using Web; using Xunit; namespace PMES.HelpDesk.Teste.IntegrationTests.Controllers { public class BasicTests : IClassFixture<HelpDeskFactory<Startup>> { private readonly HelpDeskFactory<Startup> _factory; public BasicTests(HelpDeskFactory<Startup> factory) { _factory = factory; } [Theory] [InlineData("/api/categoria")] public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url) { // Arrange var client = _factory.CreateClient(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // Act var response = await client.GetAsync(url); // Assert response.EnsureSuccessStatusCode(); Assert.Equal("text/html; charset=utf-8", response.Content.Headers.ContentType.ToString()); } } }

我很确定这与我的配置有关,但是我已经看了好几个小时,仍然找不到问题。

BasicTest.cs

using System;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PMES.HelpDesk.Infraestrutura.Context;

namespace PMES.HelpDesk.Teste.IntegrationTests.Factory
{
    public class HelpDeskFactory<TStartup> : WebApplicationFactory<TStartup> where TStartup : class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                // Remove the app's ApplicationDbContext registration.
                var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions<SGPM_HELPDESKContext>));

                if (descriptor != null)
                {
                    services.Remove(descriptor);
                }

                // Add ApplicationDbContext using an in-memory database for testing.
                services.AddDbContext<SGPM_HELPDESKContext>(options =>
                {
                    options.UseSqlite("DataSource=:memory:");
                });

                // Build the service provider.
                var sp = services.BuildServiceProvider();

                // Create a scope to obtain a reference to the database
                // context (ApplicationDbContext).
                using (var scope = sp.CreateScope())
                {
                    var scopedServices = scope.ServiceProvider;
                    var db = scopedServices.GetRequiredService<SGPM_HELPDESKContext>();
                    var logger = scopedServices.GetRequiredService<ILogger<HelpDeskFactory<TStartup>>>();

                    // Ensure the database is created.
                    db.Database.EnsureCreated();

                    try
                    {
                        // Seed the database with test data.
                        //Utilities.InitializeDbForTests(db);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "An error occurred seeding the " + "database with test messages. Error: {Message}", ex.Message);
                    }
                }
            });
        }
    }
}

Factory.cs

Message "SQLite Error 1: 'no such table: [table]'."    string

更新1

我遇到一个例外,db.Database.Migrate();。我尝试在db.Database.EnsureCreated();之后使用{{1}}更新工厂,但是仍然无法正常工作。

1 个答案:

答案 0 :(得分:1)

这是因为每次创建数据库上下文时,都会创建一个新的新的sqlite内存数据库,并且其中没有表。

您将数据库上下文配置为范围服务,并使其使用连接字符串。对于每个请求,都会创建一个新的数据库上下文,然后根据连接字符串创建一个新的连接,并在该连接中创建一个新的新数据库。里面没有桌子。

尽管您为手动创建的数据库上下文调用EnsureCreated,但这对于该实例是唯一的内存数据库,不会被其他上下文共享。

您应该创建一次sqlite连接并将其保存以备后用。

创建连接。记住要处置它。

var databaseConnection = new SqliteConnection("Data Source=:memory:;");
databaseConnection.Open();

使用该连接来配置数据库上下文。

services.AddDbContext<SGPM_HELPDESKContext>(options =>
{
    options.UseSqlite(databaseConnection);
});

您可以按需创建连接,例如针对每个测试用例。将代码插入正确的位置。

请参阅文档here