Skip to content

Commit

Permalink
Use Named.of to describe parameterized tests input (#2801)
Browse files Browse the repository at this point in the history
This commit replaces various patterns introduced to pass arguments to
parameterized tests with a meaningful description of some sort (eg. a
`String type` extra parameter, or Object[][] arrangements).

The Arguments and Named classes can be leveraged to provide a meaningful
description to a parameter other than its toString, while using the
`{argumentsWithNames}` placeholder in the test description itself.

Fixes #2788.
  • Loading branch information
simonbasle committed Oct 4, 2021
1 parent 608ca46 commit 3dfebb5
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Function;
import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.reactivestreams.Subscription;

Expand All @@ -45,6 +47,8 @@
import reactor.util.context.Context;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Named.named;
import static org.junit.jupiter.params.provider.Arguments.arguments;

public class FluxDoOnEachTest {

Expand All @@ -57,48 +61,45 @@ public void nullSource() {

private static final String sourceErrorMessage = "boomSource";

private static Object[] sourcesError() {
return new Object[] {
new Object[] { Flux.<Integer>error(new IllegalStateException(sourceErrorMessage))
.hide() },
new Object[] { Flux.<Integer>error(new IllegalStateException(sourceErrorMessage))
.hide().filter(i -> true) },
new Object[] { Flux.<Integer>error(new IllegalStateException(sourceErrorMessage)) },
new Object[] { Flux.<Integer>error(new IllegalStateException(sourceErrorMessage))
.filter(i -> true) }
};
private static Stream<Arguments> sourcesError() {
return Stream.of(
arguments(named("error", Flux.<Integer>error(new IllegalStateException(sourceErrorMessage)).hide())),
arguments(named("error (fusion)", Flux.<Integer>error(new IllegalStateException(sourceErrorMessage)))),
arguments(named("error (conditional)", Flux.<Integer>error(new IllegalStateException(sourceErrorMessage)).hide().filter(i -> true))),
arguments(named("error (fusion+conditional)", Flux.<Integer>error(new IllegalStateException(sourceErrorMessage)).filter(i -> true)))
);
}

private static Object[] sources12Complete() {
return new Object[] {
new Object[] { Flux.just(1,2).hide() },
new Object[] { Flux.just(1,2).hide().filter(i -> true) },
new Object[] { Flux.just(1,2) },
new Object[] { Flux.just(1,2).filter(i -> true) }
};
private static Stream<Arguments> sources12Complete() {
return Stream.of(
arguments(named("just(1,2)", Flux.just(1,2).hide())),
arguments(named("just(1,2) (conditional)", Flux.just(1,2).hide().filter(i -> true))),
arguments(named("just(1,2) (fusion)", Flux.just(1,2))),
arguments(named("just(1,2) (fusion+conditional)", Flux.just(1,2).filter(i -> true)))
);
}

private static Object[] sourcesEmpty() {
return new Object[] {
new Object[] { Flux.<Integer>empty().hide() },
new Object[] { Flux.<Integer>empty().hide().filter(i -> true) },
new Object[] { Flux.<Integer>empty() },
new Object[] { Flux.<Integer>empty().filter(i -> true) }
};
private static Stream<Arguments> sourcesEmpty() {
return Stream.of(
arguments(named("empty", Flux.<Integer>empty().hide())),
arguments(named("empty (conditional)", Flux.<Integer>empty().hide().filter(i -> true))),
arguments(named("empty (fusion)", Flux.<Integer>empty())),
arguments(named("empty (fusion+conditional)", Flux.<Integer>empty().filter(i -> true)))
);
}

private static Object[] sourcesNever() {
return new Object[] {
new Object[] { Flux.<Integer>never().hide() },
new Object[] { Flux.<Integer>never().hide().filter(i -> true) },
new Object[] { Flux.<Integer>never() },
new Object[] { Flux.<Integer>never().filter(i -> true) }
};
private static Stream<Arguments> sourcesNever() {
return Stream.of(
arguments(named("never", Flux.<Integer>never().hide())),
arguments(named("never (conditional)", Flux.<Integer>never().hide().filter(i -> true))),
arguments(named("never (fusion)", Flux.<Integer>never())),
arguments(named("never (fusion+conditional)", Flux.<Integer>never().filter(i -> true)))
);
}

@ParameterizedTestWithName
@MethodSource("sources12Complete")
public void normal(Flux<Integer> source) {
void normal(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();

AtomicReference<Integer> onNext = new AtomicReference<>();
Expand Down Expand Up @@ -296,7 +297,7 @@ public void fusedAsyncCallbackErrorsOnTerminal() {

@ParameterizedTestWithName
@MethodSource("sourcesError")
public void error(Flux<Integer> source) {
void error(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();

AtomicReference<Integer> onNext = new AtomicReference<>();
Expand Down Expand Up @@ -329,7 +330,7 @@ else if (s.isOnComplete()) {

@ParameterizedTestWithName
@MethodSource("sourcesEmpty")
public void empty(Flux<Integer> source) {
void empty(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();

AtomicReference<Integer> onNext = new AtomicReference<>();
Expand Down Expand Up @@ -361,7 +362,7 @@ else if (s.isOnComplete()) {

@ParameterizedTestWithName
@MethodSource("sourcesNever")
public void never(Flux<Integer> source) {
void never(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();

AtomicReference<Integer> onNext = new AtomicReference<>();
Expand Down Expand Up @@ -393,7 +394,7 @@ else if (s.isOnComplete()) {

@ParameterizedTestWithName
@MethodSource("sources12Complete")
public void nextCallbackError(Flux<Integer> source) {
void nextCallbackError(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();
LongAdder state = new LongAdder();

Expand All @@ -416,7 +417,7 @@ public void nextCallbackError(Flux<Integer> source) {

@ParameterizedTestWithName
@MethodSource("sources12Complete")
public void nextCallbackBubbleError(Flux<Integer> source) {
void nextCallbackBubbleError(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();
LongAdder state = new LongAdder();

Expand All @@ -443,7 +444,7 @@ public void nextCallbackBubbleError(Flux<Integer> source) {

@ParameterizedTestWithName
@MethodSource("sources12Complete")
public void completeCallbackError(Flux<Integer> source) {
void completeCallbackError(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();
AtomicBoolean completeHandled = new AtomicBoolean();
AtomicBoolean errorHandled = new AtomicBoolean();
Expand Down Expand Up @@ -472,7 +473,7 @@ public void completeCallbackError(Flux<Integer> source) {

@ParameterizedTestWithName
@MethodSource("sourcesError")
public void errorCallbackError(Flux<Integer> source) {
void errorCallbackError(Flux<Integer> source) {
AssertSubscriber<Integer> ts = AssertSubscriber.create();
LongAdder state = new LongAdder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.stream.Stream;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mockito;
import org.reactivestreams.Publisher;
Expand All @@ -50,6 +52,8 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
import static org.junit.jupiter.api.Named.named;
import static org.junit.jupiter.params.provider.Arguments.arguments;

public class FluxUsingWhenTest {

Expand Down Expand Up @@ -695,12 +699,12 @@ public void apiRollbackGeneratingNull(Flux<String> transactionWithError) {

@ParameterizedTestWithName
@MethodSource("sourcesFullTransaction")
public void apiCancel(Flux<String> transactionWithError) {
public void apiCancel(Flux<String> transactionToCancel) {
final AtomicReference<TestResource> ref = new AtomicReference<>();
Flux<String> flux = Flux.usingWhen(Mono.fromCallable(TestResource::new),
d -> {
ref.set(d);
return transactionWithError;
return transactionToCancel;
},
TestResource::commit,
TestResource::rollback,
Expand Down Expand Up @@ -758,15 +762,15 @@ public void apiCancelFailure(Flux<String> transaction) {

@ParameterizedTestWithName
@MethodSource("sourcesFullTransaction")
public void apiCancelGeneratingNullLogs(Flux<String> transactionWithError) {
public void apiCancelGeneratingNullLogs(Flux<String> transactionToCancel) {
TestLogger testLogger = new TestLogger();
Loggers.useCustomLoggers(s -> testLogger);
try {
final AtomicReference<TestResource> ref = new AtomicReference<>();
Flux<String> flux = Flux.usingWhen(Mono.fromCallable(TestResource::new),
d -> {
ref.set(d);
return transactionWithError;
return transactionToCancel;
},
TestResource::commit,
TestResource::rollback,
Expand Down Expand Up @@ -1418,50 +1422,52 @@ public Flux<Integer> cancelNull() {

//unit test parameter providers

private static Object[] sources01() {
return new Object[] {
new Object[] { Flux.interval(Duration.ofMillis(100)).map(String::valueOf) },
new Object[] { Flux.range(0, 2).map(String::valueOf) }
};
private static Stream<Arguments> sources01() {
return Stream.of(
arguments(named("interval(100ms).map(toString)", Flux.interval(Duration.ofMillis(100)).map(String::valueOf))),
arguments(named("range(0,2).map(toString)", Flux.range(0, 2).map(String::valueOf)))
);
}

private static Object[] sourcesFullTransaction() {
return new Object[] {
new Object[] { Flux.just("Transaction started", "work in transaction", "more work in transaction").hide() },
new Object[] { Flux.just("Transaction started", "work in transaction", "more work in transaction") }
};
private static Stream<Arguments> sourcesFullTransaction() {
return Stream.of(
arguments(named("(start,wip1,wip2)", Flux.just("Transaction started", "work in transaction", "more work in transaction").hide())),
arguments(named("(start,wip1,wip2) (fusion)", Flux.just("Transaction started", "work in transaction", "more work in transaction")))
);
}

private static Object[] sourcesTransactionError() {
return new Object[] {
new Object[] { Flux.just("Transaction started", "work in transaction")
.concatWith(Mono.error(new IllegalStateException("boom"))) },
new Object[] { Flux.just("Transaction started", "work in transaction", "boom")
.map(v -> { if (v.length() > 4) return v; else throw new IllegalStateException("boom"); } ) }
};
private static Stream<Arguments> sourcesTransactionError() {
return Stream.of(
arguments(named("(start,wip,ERROR)",
Flux.just("Transaction started", "work in transaction")
.concatWith(Mono.error(new IllegalStateException("boom")))
)),
arguments(named("(start,wip,ERROR) (fusion)",
Flux.just("Transaction started", "work in transaction", "boom")
.map(v -> { if (v.length() > 4) return v; else throw new IllegalStateException("boom"); })
))
);
}

private static Object[] sourcesContext() {
return new Object[] {
new Object[] { Mono.deferContextual(Mono::just).map(it -> it.get(String.class)).hide() },
new Object[] { Mono.deferContextual(Mono::just).map(it -> it.get(String.class)) }
};
private static Stream<Arguments> sourcesContext() {
return Stream.of(
arguments(named("deferContextual", Mono.deferContextual(Mono::just).map(it -> it.get(String.class)).hide())),
arguments(named("deferContextual (fusion)", Mono.deferContextual(Mono::just).map(it -> it.get(String.class))))
);
}

private static Object[] sourcesContextError() {
return new Object[] {
new Object[] { Mono
.deferContextual(Mono::just)
.map(it -> it.get(String.class))
.hide()
.map(it -> { throw new IllegalStateException("boom"); })
},
new Object[] { Mono
.deferContextual(Mono::just)
.map(it -> it.get(String.class))
.map(it -> { throw new IllegalStateException("boom"); })
}
};
private static Stream<Arguments> sourcesContextError() {
return Stream.of(
arguments(named("deferContextual+error",
Mono.deferContextual(Mono::just)
.map(it -> it.get(String.class))
.hide()
.map(it -> { throw new IllegalStateException("boom"); }))),
arguments(named("deferContextual+error (fusion)",
Mono.deferContextual(Mono::just)
.map(it -> it.get(String.class))
.map(it -> { throw new IllegalStateException("boom"); })))
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,17 @@
import java.util.function.Function;
import java.util.stream.Stream;

import org.assertj.core.api.ThrowableAssert;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.reactivestreams.Subscription;

import reactor.core.CoreSubscriber;
import reactor.core.Disposable;
import reactor.core.Scannable;
import reactor.core.scheduler.Schedulers;
import reactor.test.ParameterizedTestWithName;
import reactor.test.StepVerifier;
import reactor.test.publisher.MonoOperatorTest;
import reactor.test.publisher.TestPublisher;
Expand All @@ -43,6 +44,8 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Named.named;
import static org.junit.jupiter.params.provider.Arguments.arguments;

public class MonoCacheTimeTest extends MonoOperatorTest<String, String> {

Expand Down Expand Up @@ -937,24 +940,24 @@ private void assertCacheTtl(Mono<Integer> mono, Duration ttl, AtomicInteger subC
assertThat(subCount.get()).isEqualTo(2);
}

@ParameterizedTest(name = "{displayName} [for null case #{index}]")
@ParameterizedTestWithName
@MethodSource("nullInvocations")
public void nullArgumentsToCacheOperatorsAreImmediatelyRejected(ThrowableAssert.ThrowingCallable nullInvocation) { //TODO replace with Named.of in JUnit 5.8+
assertThatExceptionOfType(NullPointerException.class).isThrownBy(nullInvocation);
void nullArgumentsToCacheOperatorsAreImmediatelyRejected(ThrowingCallable type) {
assertThatExceptionOfType(NullPointerException.class).isThrownBy(type);
}

private static Stream<ThrowableAssert.ThrowingCallable> nullInvocations() {
private static Stream<Arguments> nullInvocations() {
return Stream.of(
() -> Mono.empty().cache(null),
() -> Mono.empty().cache(null, Schedulers.parallel()),
() -> Mono.empty().cache(Duration.ZERO, null),
() -> Mono.empty().cache(null, e -> Duration.ZERO, () -> Duration.ZERO),
() -> Mono.empty().cache(v -> Duration.ZERO, null, () -> Duration.ZERO),
() -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, null),
() -> Mono.empty().cache(null, e -> Duration.ZERO, () -> Duration.ZERO, Schedulers.parallel()),
() -> Mono.empty().cache(v -> Duration.ZERO, null, () -> Duration.ZERO, Schedulers.parallel()),
() -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, null, Schedulers.parallel()),
() -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, () -> Duration.ZERO, null)
arguments(named("cache(null)", (ThrowingCallable) () -> Mono.empty().cache(null))),
arguments(named("cache(null,parallel)", (ThrowingCallable) () -> Mono.empty().cache(null, Schedulers.parallel()))),
arguments(named("cache(ZERO,null)", (ThrowingCallable) () -> Mono.empty().cache(Duration.ZERO, null))),
arguments(named("cache(null,e->ZERO,()->ZERO)", (ThrowingCallable) () -> Mono.empty().cache(null, e -> Duration.ZERO, () -> Duration.ZERO))),
arguments(named("cache(v->ZERO,null,()->ZERO)", (ThrowingCallable) () -> Mono.empty().cache(v -> Duration.ZERO, null, () -> Duration.ZERO))),
arguments(named("cache(v->ZERO,e->ZERO,null)", (ThrowingCallable) () -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, null))),
arguments(named("cache(null,e->ZERO,()->ZERO,parallel)", (ThrowingCallable) () -> Mono.empty().cache(null, e -> Duration.ZERO, () -> Duration.ZERO, Schedulers.parallel()))),
arguments(named("cache(v->ZERO,null,()->ZERO,parallel)", (ThrowingCallable) () -> Mono.empty().cache(v -> Duration.ZERO, null, () -> Duration.ZERO, Schedulers.parallel()))),
arguments(named("cache(v->ZERO,e->ZERO,null,parallel)", (ThrowingCallable) () -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, null, Schedulers.parallel()))),
arguments(named("cache(v->ZERO,e->ZERO,()->ZERO,null)", (ThrowingCallable) () -> Mono.empty().cache(v -> Duration.ZERO, e -> Duration.ZERO, () -> Duration.ZERO, null)))
);
}
}

0 comments on commit 3dfebb5

Please sign in to comment.