Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move test subscribers to the public API #352

Merged
merged 5 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;
import io.smallrye.mutiny.infrastructure.Infrastructure;
import io.smallrye.mutiny.test.AssertSubscriber;

public class MultiContextPropagationTest {

Expand Down
28 changes: 27 additions & 1 deletion documentation/src/main/docs/faq.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -794,4 +794,30 @@ include::../../../src/test/java/snippets/PlugTest.java[tags=custom-operator]
====
Custom operators are an advanced feature: when possible please use the existing operators and use helpers such as `stage` to write readable code.
In the case of custom `Multi` operators it is wise to test them against the _Reactive Streams TCK_.
====
====

== How can I write unit / integration tests?

Mutiny provides subscribers for `Uni` and `Multi` offering helpful assertion methods.
You can use them to test pipelines.

Here is an example to test a `Uni`:

[source,java,indent=0]
----
include::../../../src/test/java/snippets/TestSubscribersTest.java[tags=uni]
----

Testing a `Multi` pipeline is similar:

[source,java,indent=0]
----
include::../../../src/test/java/snippets/TestSubscribersTest.java[tags=multi]
----

The assertions do not just focus on _good_ outcomes, you can also test failures as in:

[source,java,indent=0]
----
include::../../../src/test/java/snippets/TestSubscribersTest.java[tags=failing]
----
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor;
import io.smallrye.mutiny.test.AssertSubscriber;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;
import org.junit.jupiter.api.Test;

public class BroadcastProcessorTest {
Expand Down
2 changes: 1 addition & 1 deletion documentation/src/test/java/snippets/PaginationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.test.AssertSubscriber;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
Expand Down
50 changes: 50 additions & 0 deletions documentation/src/test/java/snippets/TestSubscribersTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package snippets;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;
import org.junit.jupiter.api.Test;

import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.helpers.test.UniAssertSubscriber;

import java.io.IOException;

public class TestSubscribersTest {

@Test
void uni() {
// tag::uni[]
Uni<Integer> uni = Uni.createFrom().item(63);

UniAssertSubscriber<Integer> subscriber = uni
.subscribe().withSubscriber(UniAssertSubscriber.create());

subscriber.assertCompleted().assertItem(63);
// end::uni[]
}

@Test
void multi() {
// tag::multi[]
Multi<Integer> multi = Multi.createFrom().range(1, 5)
.onItem().transform(n -> n * 10);

AssertSubscriber<Integer> subscriber = multi.subscribe().withSubscriber(AssertSubscriber.create(10));

subscriber.assertCompleted()
.assertItems(10, 20, 30, 40);
// end::multi[]
}

@Test
void failing() {
// tag::failing[]
Multi<Object> multi = Multi.createFrom().failure(() -> new IOException("Boom"));

AssertSubscriber<Object> subscriber = multi
.subscribe().withSubscriber(AssertSubscriber.create(10));

subscriber.assertFailedWith(IOException.class, "Boom");
// end::failing[]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.operators.multi.processors.UnicastProcessor;
import io.smallrye.mutiny.test.AssertSubscriber;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;

public class UnicastProcessorTest {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
package io.smallrye.mutiny.test;
package io.smallrye.mutiny.helpers.test;

import java.util.concurrent.atomic.AtomicReference;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

/**
* A convenient base class for a subscriber and subscription to extend in tests and that manages the subscription and
* requests.
* <p>
*
* Implementations shall override {@link AbstractSubscriber#onNext(Object)},
* {@link AbstractSubscriber#onError(Throwable)} and/or {@link AbstractSubscriber#onComplete()} to add test-specific
* custom logic.
*
* @param <T> the type of the items
*/
@SuppressWarnings("SubscriberImplementation")
public class AbstractSubscriber<T> implements Subscriber<T>, Subscription {

private final long upfrontRequest;

/**
* Creates a new {@link AbstractSubscriber} with 0 upfront requests.
*/
public AbstractSubscriber() {
upfrontRequest = 0;
}

/**
* Creates a new {@link AbstractSubscriber} with {@code req} upfront requests.
*
* @param req the number of upfront requests
*/
public AbstractSubscriber(long req) {
upfrontRequest = req;
}
Expand Down
Loading