Поток возвращает несортированные данные для StepVerifier

#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/…