#spring #kotlin #spring-webflux
Вопрос:
Я ожидаю получить два элемента после записи трех в базу данных. Запрос возвращает поток, который возвращает элементы несортированными.
@Test
fun `SUCESSFULLY query pending purchases`() {
// arrange
val arrived = TestDataFactory.buchungssatzEntity(
sequentialId = 1,
arrived = true
)
val pending = TestDataFactory.buchungssatzEntity(
sequentialId = 2,
arrived = false
)
val next_pending = TestDataFactory.buchungssatzEntity(
sequentialId = 3,
arrived = false
)
// act
buchhaltungWriter.save(arrived)
buchhaltungWriter.save(pending)
buchhaltungWriter.save(next_pending)
val purchases = inventoryFinder.findAllPendingPurchases()
// assert
StepVerifier.create(purchases)
.expectNext(pending)
.expectNext(next_pending)
.verifyComplete()
}
Это всегда бросает
ожидаемое значение: доходность(… последовательный идентификатор = 2 …); фактическое значение: доходность(… последовательный идентификатор=3 …)
Я не хочу добавлять сортировку в запрос базы данных, это пустая трата времени. Как я могу протестировать поток со «всеми этими элементами, но в любом порядке», или в этом случае я должен просто пойти на Моно, вернуть список и сделать все остальное сам? Опять же, я не поэтому использую reactive.
PS: Цель этого теста-убедиться, что мои операторы языка запросов Spring фильтруются правильно.
——— ОБНОВЛЕНИЕ
Я решил эту проблему с помощью
StepVerifier.create(inventoryFinder.findAllPendingPurchases())
.recordWith { listOf<PurchasesModel>() }
.thenConsumeWhile { i: Any? -> purchases.contains(i) }
.consumeRecordedWith{ }
.verifyComplete()
Комментарии:
1. любой запрос к любой базе данных никогда не гарантирует никакого порядка, если вы не предоставите
ORDERED BY
, поэтому никогда не предполагайте, что данные будут извлечены в том виде, в каком вы их вставили.2. Я знаю, почему я спрашиваю, как я могу правильно проверить это в реактивном env
Ответ №1:
Один из способов сделать это-использовать thenConsumeWhile
оператора вместе с expectNextCount
. Если в последовательности есть какой-либо элемент, который не совпадает, StepVerifier выдаст ошибку.
На Яве:
List<Item> pendingItems = List.of(pending, next_pending);
Flux<Item> items = inventoryFinder.findAllPendingPurchases();
StepVerifier.create(items)
.expectNextCount(2) //expecting 2 elements
.verifyComplete();
StepVerifier.create(items)
.thenConsumeWhile((i) -> pendingItems.contains(i)) // check if element was expected
.verifyComplete();
Комментарии:
1. Это не работает : / Сбой с тем же сообщением об ошибке, я думаю, он ожидает, что оно поступит в том же порядке. Таким образом, ваше решение, похоже, в точности соответствует моему, но вы передаете список вместо двух явных
next
вызовов2. @nykon Вы правы, я обновил свой ответ.
3. Это все еще не работает, но я понимаю идею. Теперь я понимаю
expected: onComplete(); actual: onNext(BuchungssatzEntity(id=c637
, но я думаю, что направление правильное4. @nykon Не могли бы вы опубликовать свой код? Вы ожидаете трех элементов, поэтому у вас должно быть
.expectNextCount(3)
5. Извините за задержку — текущий код можно найти здесь: github.com/rainerknabenbauer/ecommerce-bay/blob/main/backend/…