Я следовал стратегиям настройки тестов для API ASP.NET Core 2.2 с использованием документации Microsoft по адресу Интеграционные тесты в ASP.NET Core .
Подводя итог,мы расширяем и настраиваем WebApplicationFactory
и используем IWebHostBuilder
для установки и настройки различных служб, чтобы предоставить нам контекст базы данных, используя базу данных в памяти для тестирования, как показано ниже (скопировано и вставлено из статьи):
public class CustomWebApplicationFactory<TStartup>
: WebApplicationFactory<TStartup> where TStartup: class
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureServices(services =>
{
// Create a new service provider.
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
// Add a database context (ApplicationDbContext) using an in-memory
// database for testing.
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseInMemoryDatabase("InMemoryDbForTesting");
options.UseInternalServiceProvider(serviceProvider);
});
// 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<ApplicationDbContext>();
var logger = scopedServices
.GetRequiredService<ILogger<CustomWebApplicationFactory<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: {ex.Message}");
}
}
});
}
}
В тестах мы можем использовать фабрику и создать клиента следующим образом:
public class IndexPageTests :
IClassFixture<CustomWebApplicationFactory<RazorPagesProject.Startup>>
{
private readonly HttpClient _client;
private readonly CustomWebApplicationFactory<RazorPagesProject.Startup>
_factory;
public IndexPageTests(
CustomWebApplicationFactory<RazorPagesProject.Startup> factory)
{
_factory = factory;
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
}
[Fact]
public async Task Test1()
{
var response = await _client.GetAsync("/api/someendpoint");
}
}
Это работает нормально, но обратите внимание на вызов InitializeDbForTests
, который устанавливает некоторые тестовые данные для всех тестов, когдаслужбы настроены.
Я бы хотел разумную стратегию для запуска каждого теста API с чистого листа, чтобы тесты не зависели друг от друга.Я искал различные способы овладеть ApplicationDbContext
в моих методах испытаний, но безрезультатно.
Было бы разумно проводить интеграционные тесты в полной изоляции друг от друга, и как я мог подойтиэто с помощью ASP.NET Core / EF Core / xUnit.NET?