Документация

Koto.Testing.Integration

Кирпичики для интеграционных тестов: тестовая авторизация через заголовок, проверки Eventually и продюсер raw-JSON в Kafka.

Что внутри

ТипНазначение
AddHeaderTestAuthentication() / WithTestUser(...)Заменяют настоящую авторизацию (JWKS, JWT) на схему по заголовкам
Eventually.AssertAsync(...)Проверка асинхронных эффектов опросом
RawJsonKafkaProducerПубликация raw-JSON интеграционных контрактов из теста

Своей зависимости от Testcontainers у пакета нет: жизненный цикл контейнеров остаётся в вашей фикстуре, поэтому эти блоки собираются с любой раскладкой хоста — один сервис, сага из нескольких сервисов или in-memory TestServer.

Тестовая авторизация по заголовкам

Заменяет настоящую авторизацию хоста на схему, управляемую заголовками запроса X-Test-UserId / X-Test-Role, — тестам не нужно выпускать настоящие JWT:

Factory = new WebApplicationFactory<Program>().WithWebHostBuilder(builder =>
{
    builder.ConfigureServices(services => services.AddHeaderTestAuthentication());
});

using var client = Factory.CreateClient().WithTestUser(userId);           // участник
using var admin  = Factory.CreateClient().WithTestUser(adminId, "Admin"); // проверка роли

Eventually

Проверка асинхронных эффектов опросом — Kafka-консьюмеры, проекции, саги. Описание попадает в сообщение о таймауте, поэтому падение сразу говорит, что именно так и не случилось:

await Eventually.AssertAsync(async () =>
{
    var detail = await client.GetFromJsonAsync<JsonElement>($"/meetups/{id}");
    return detail.GetProperty("status").GetString() == "Settled";
}, TimeSpan.FromSeconds(45), "meetup becomes Settled");

RawJsonKafkaProducer

Публикует обычный web-cased JSON — ровно то, что выдаёт PublishIntegrationEvents (Koto.Messaging.Wolverine), — так что тест может сымитировать вышестоящий сервис или повторную доставку. Топик берётся из public const string Topic контракта (общая конвенция через IntegrationEventTopics в Koto.Application):

using var kafka = new RawJsonKafkaProducer(kafkaContainer.GetBootstrapAddress());
await kafka.PublishAsync(new UserRegisteredV1(userId, null, "Ivan", ["ru"])); // топик выводится из типа
await kafka.PublishAsync("explicit.topic", payload);                          // или явно