我正在构建我的第一个系统,并试图维护测试等良好实践。
现在,我的集成测试设置面临问题。我只是跟随 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());
}
}
}
我很确定这与我的配置有关,但是我已经看了好几个小时,仍然找不到问题。
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);
}
}
});
}
}
}
Message "SQLite Error 1: 'no such table: [table]'." string
我遇到一个例外,db.Database.Migrate();
。我尝试在db.Database.EnsureCreated();
之后使用{{1}}更新工厂,但是仍然无法正常工作。
答案 0 :(得分:1)
这是因为每次创建数据库上下文时,都会创建一个新的新的sqlite内存数据库,并且其中没有表。
您将数据库上下文配置为范围服务,并使其使用连接字符串。对于每个请求,都会创建一个新的数据库上下文,然后根据连接字符串创建一个新的连接,并在该连接中创建一个新的新数据库。里面没有桌子。
尽管您为手动创建的数据库上下文调用EnsureCreated
,但这对于该实例是唯一的内存数据库,不会被其他上下文共享。
您应该创建一次sqlite连接并将其保存以备后用。
创建连接。记住要处置它。
var databaseConnection = new SqliteConnection("Data Source=:memory:;");
databaseConnection.Open();
使用该连接来配置数据库上下文。
services.AddDbContext<SGPM_HELPDESKContext>(options =>
{
options.UseSqlite(databaseConnection);
});
您可以按需创建连接,例如针对每个测试用例。将代码插入正确的位置。
请参阅文档here。