Утверждения о недетерминированном поведении

Имеет ли AssertJ (или JUnit) способ объединить в одном (свободном) выражении несколько утверждений на одном и том же тестируемом модуле, где одно из утверждений может вызвать исключение. По сути, я пытаюсь утверждать, что:

Если тестируемый модуль (X) не приводит к конкретному исключению, которое может произойти, тогда утверждают, что определенное свойство в тестируемом модуле не сохраняется. В противном случае утверждают, что исключение имеет определенный тип.

Например, есть ли способ выразить утверждение, что следующий ошибочный код может ИЛИ привести к исключению или к ситуации, в которой strings.size ()! = 10000:

@Test/*(expected=ArrayIndexOutOfBoundsException.class)*/
public void raceConditions() throws Exception {


    List<String> strings = new ArrayList<>(); //not thread-safe

    Stream.iterate("+", s -> s+"+")
    .parallel()
    .limit(10000)
    //.peek(e -> System.out.println(e+" is processed by "+ Thread.currentThread().getName()))
    .forEach(e -> strings.add(e));

    System.out.println("# of elems: "+strings.size());
} 

AssertJ имеет концепцию мягких утверждений, которые будут использоваться в подобных сценариях? Буду признателен за некоторые примеры кода, если так.

Или, может быть, есть лучшие фреймворки, специально разработанные для этого типа сценариев?

Благодарю.

2 ответа

Решение

Я не уверен, что это то, что вы действительно ищете, но вы можете попробовать использовать предположения. После выполнения тестируемого кода выполните предположение о результате, следующий код / ​​утверждения будут выполняться только в том случае, если предположения были правильными.

Начиная с версии 3.9.0 AssertJ предоставляет исходные предположения, например:

List<String> strings = new ArrayList<>(); // not thread-safe

int requestedSize = 10_000;

Throwable thrown = catchThrowable(() -> {
  Stream.iterate("+", s -> s + "+")
        .parallel()
        .limit(requestedSize)
        .forEach(strings::add);
});

// thrown is null if there was no exception raised
assumeThat(thrown).isNotNull();

// only executed if thrown was not null otherwise the test is skipped.
assertThat(thrown).isInstanceOf(ArrayIndexOutOfBoundsException.class);

Вам также следует взглянуть на https://github.com/awaitility/awaitility если вы тестируете асинхронный код.

Я придумал следующее:

 @Test
 public void testRaceConditions() {
    List<String> strings = new ArrayList<>(); //not thread-safe

    int requestedSize = 10_000;

    Throwable thrown = catchThrowable(() -> { 
    Stream.iterate("+", s -> s+"+")
    .parallel()
    .limit(requestedSize)
    //.peek(e -> System.out.println(e+" is processed by "+ Thread.currentThread().getName()))
    .forEach(e -> strings.add(e));
    });

    SoftAssertions.assertSoftly(softly -> {
         softly.assertThat(strings.size()).isNotEqualTo(requestedSize);
         softly.assertThat(thrown).isInstanceOf(ArrayIndexOutOfBoundsException.class);
     });

 }

Если бы кто-то с большим количеством AssertJ под прицелом или другими инструментами знал о лучшем способе, я бы с радостью принял их решения. Спасибо!

Другие вопросы по тегам