
In-memory база врёт: 5 расхождений с продовой БД
vsinyavsky 12 минут назад In-memory база врёт: 5 расхождений с продовой БД Средний 11 мин 371 .NET * C# * Программирование * Тестирование IT-систем * Базы данных * Кейс Есть неприятный тип зелёного теста: он проверяет...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Вот важная новость с фронта ИИ: vsinyavsky 12 минут назад In-memory база врёт: 5 расхождений с продовой БД Средний 11 мин 371 . NET * C# * Программирование * Тестирование IT-систем * Базы данных * Кейс Есть неприятный тип зелёного теста: он проверяет нашу фантазию о базе. В платежах это видно особенно заметно.
Ситуация: поллер статуса выбирает Pending-платежи, тест на List. AsQueryable() проходит, а на проде всплывает транслятор запросов, уникальный индекс, сортировка или гонка двух воркеров. Код тот же, уверенность та же, результат другой.
Технические детали
В прошлой статье про интеграцию без песочницы я рассказывал, как мы писали стаб банка по pdf-файлу со спецификацией. Стаб был полезен, но закрепил нашу картину протокола. С in-memory базой в тестах происходит похожая вещь: она закрепляет нашу картину поведения БД.
Я не предлагаю тащить контейнер с Postgres или Mongo в каждый unit-тест. Вопрос начинается там, где тест якобы проверяет запрос к базе, уникальный индекс, сортировку, транзакцию или работу двух воркеров. Ниже будет пример именно из этой зоны: фоновый поллер платежей, который выбирает незавершённые оплаты и спрашивает банк об их актуальном статусе.
Тест, которому хочется веритьПосле истории с потерянными нотификациями в платёжном агрегаторе появляется фоновый воркер. Он берёт платежи в статусе Pending, по которым уже пора спросить банк, и отправляет запрос статуса напрямую провайдеру. public interface public enum public sealed record PaymentDocument( Guid Id, string?
Отраслевые последствия
ProviderPaymentId, PaymentStatus Status, DateTimeOffset CreatedAt, DateTimeOffset? NextStatusCheckAt) { public bool ShouldCheckStatus(DateTimeOffset now) => Status == PaymentStatus. Pending && ProviderPaymentId is not null && NextStatusCheckAt.
HasValue && NextStatusCheckAt. Value <= now && CreatedAt > now. AddDays(-2); } public sealed class PendingPaymentQuery(IPaymentReadStore store) { public IReadOnlyList TakeDueForStatusCheck(DateTimeOffset now) => store.
ShouldCheckStatus(now)) . ToList(); } Такой код даже хочется похвалить. Условие не размазано по запросу, имя метода говорит доменным языком, тест получается коротким.
Событие, по словам экспертов, усилит конкуренцию в сфере ИИ.





