Skip to content

Commit

Permalink
#266 - Refactor reactive tests to use StepVerifier and test methods.
Browse files Browse the repository at this point in the history
We now use StepVerifier and RxJava's .test() methods instead of .block() calls. Using blocking methods is an anti pattern which should be avoided within tests. Test API comes with timeouts and protects tests from never completing.
  • Loading branch information
mp911de committed Dec 1, 2017
1 parent a2f963d commit 69c2c2a
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 237 deletions.
6 changes: 6 additions & 0 deletions cassandra/reactive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
<artifactId>rxjava-reactive-streams</artifactId>
</dependency>

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>spring-data-cassandra-example-utils</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

import example.springdata.cassandra.util.CassandraKeyspace;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import rx.RxReactiveStreams;

import java.util.concurrent.CountDownLatch;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
Expand Down Expand Up @@ -52,37 +52,33 @@ public class ReactiveCassandraTemplateIntegrationTest {
@Before
public void setUp() {

template.truncate(Person.class) //
Flux<Person> truncateAndInsert = template.truncate(Person.class) //
.thenMany(Flux.just(new Person("Walter", "White", 50), //
new Person("Skyler", "White", 45), //
new Person("Saul", "Goodman", 42), //
new Person("Jesse", "Pinkman", 27))) //
.flatMap(template::insert) //
.then() //
.block();
.flatMap(template::insert);

StepVerifier.create(truncateAndInsert).expectNextCount(4).verifyComplete();
}

/**
* This sample performs a count, inserts data and performs a count again using reactive operator chaining. It prints
* the two counts ({@code 4} and {@code 6}) to the console.
*/
@Test
public void shouldInsertAndCountData() throws Exception {
public void shouldInsertAndCountData() {

CountDownLatch countDownLatch = new CountDownLatch(1);

template.count(Person.class) //
Mono<Long> saveAndCount = template.count(Person.class) //
.doOnNext(System.out::println) //
.thenMany(Flux.just(new Person("Hank", "Schrader", 43), //
new Person("Mike", "Ehrmantraut", 62)))
.flatMap(template::insert) //
.last() //
.flatMap(v -> template.count(Person.class)) //
.doOnNext(System.out::println) //
.doOnTerminate(countDownLatch::countDown) //
.subscribe();
.doOnNext(System.out::println);

countDownLatch.await();
StepVerifier.create(saveAndCount).expectNext(6L).verifyComplete();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
*/
package example.springdata.cassandra.people;

import static org.assertj.core.api.Assertions.*;

import example.springdata.cassandra.util.CassandraKeyspace;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import reactor.test.StepVerifier;

import org.junit.Before;
import org.junit.ClassRule;
Expand Down Expand Up @@ -51,90 +47,66 @@ public class ReactivePersonRepositoryIntegrationTest {
@Before
public void setUp() {

repository.deleteAll() //
Flux<Person> deleteAndInsert = repository.deleteAll() //
.thenMany(repository.saveAll(Flux.just(new Person("Walter", "White", 50), //
new Person("Skyler", "White", 45), //
new Person("Saul", "Goodman", 42), //
new Person("Jesse", "Pinkman", 27))))
.then() //
.block();
new Person("Jesse", "Pinkman", 27))));

StepVerifier.create(deleteAndInsert).expectNextCount(4).verifyComplete();
}

/**
* This sample performs a count, inserts data and performs a count again using reactive operator chaining.
*/
@Test
public void shouldInsertAndCountData() throws Exception {

CountDownLatch countDownLatch = new CountDownLatch(1);
public void shouldInsertAndCountData() {

repository.count() //
Mono<Long> saveAndCount = repository.count() //
.doOnNext(System.out::println) //
.thenMany(repository.saveAll(Flux.just(new Person("Hank", "Schrader", 43), //
new Person("Mike", "Ehrmantraut", 62)))) //
.last() //
.flatMap(v -> repository.count()) //
.doOnNext(System.out::println) //
.doOnTerminate(countDownLatch::countDown) //
.subscribe();
.doOnNext(System.out::println);

countDownLatch.await();
StepVerifier.create(saveAndCount).expectNext(6L).verifyComplete();
}

/**
* Result set {@link com.datastax.driver.core.Row}s are converted to entities as they are emitted. Reactive pull and
* prefetch define the amount of fetched records.
*/
@Test
public void shouldPerformConversionBeforeResultProcessing() throws Exception {

CountDownLatch countDownLatch = new CountDownLatch(1);

repository.findAll() //
.doOnNext(System.out::println) //
.doOnComplete(countDownLatch::countDown) //
.doOnError(throwable -> countDownLatch.countDown()) //
.subscribe();
public void shouldPerformConversionBeforeResultProcessing() {

countDownLatch.await();
StepVerifier.create(repository.findAll().doOnNext(System.out::println)) //
.expectNextCount(4) //
.verifyComplete();
}

/**
* Fetch data using query derivation.
*/
@Test
public void shouldQueryDataWithQueryDerivation() {

List<Person> whites = repository.findByLastname("White") //
.collectList() //
.block();

assertThat(whites).hasSize(2);
StepVerifier.create(repository.findByLastname("White")).expectNextCount(2).verifyComplete();
}

/**
* Fetch data using a string query.
*/
@Test
public void shouldQueryDataWithStringQuery() {

Person heisenberg = repository.findByFirstnameInAndLastname("Walter", "White") //
.block();

assertThat(heisenberg).isNotNull();
StepVerifier.create(repository.findByFirstnameInAndLastname("Walter", "White")).expectNextCount(1).verifyComplete();
}

/**
* Fetch data using query derivation.
*/
@Test
public void shouldQueryDataWithDeferredQueryDerivation() {

List<Person> whites = repository.findByLastname(Mono.just("White")) //
.collectList() //
.block();

assertThat(whites).hasSize(2);
StepVerifier.create(repository.findByLastname(Mono.just("White"))).expectNextCount(2).verifyComplete();
}

/**
Expand All @@ -143,10 +115,9 @@ public void shouldQueryDataWithDeferredQueryDerivation() {
@Test
public void shouldQueryDataWithMixedDeferredQueryDerivation() {

Person heisenberg = repository.findByFirstnameAndLastname(Mono.just("Walter"), "White") //
.block();

assertThat(heisenberg).isNotNull();
StepVerifier.create(repository.findByFirstnameAndLastname(Mono.just("Walter"), "White")) //
.expectNextCount(1) //
.verifyComplete();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,11 @@
*/
package example.springdata.cassandra.people;

import static org.assertj.core.api.Assertions.*;

import example.springdata.cassandra.util.CassandraKeyspace;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.Single;

import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
Expand Down Expand Up @@ -60,16 +55,16 @@ public void setUp() throws Exception {
new Person("Saul", "Goodman", 42), //
new Person("Jesse", "Pinkman", 27)));

deleteAll.andThen(save).blockingLast();
deleteAll.andThen(save).test().await().assertNoErrors();
}

/**
* This sample performs a count, inserts data and performs a count again using reactive operator chaining.
* This sample performs a count, inserts data and performs a count again using reactive operator chaining. It prints
* the two counts ({@code 4} and {@code 6}) to the console.
*/
@Test
public void shouldInsertAndCountData() throws Exception {
public void shouldInsertAndCountData() {

CountDownLatch countDownLatch = new CountDownLatch(1);

repository.count() //
.doOnSuccess(System.out::println) //
Expand All @@ -80,28 +75,26 @@ public void shouldInsertAndCountData() throws Exception {
.toSingle() //
.flatMap(v -> repository.count()) //
.doOnSuccess(System.out::println) //
.doAfterTerminate(countDownLatch::countDown) //
.subscribe();

countDownLatch.await();
.test() //
.awaitCount(1) //
.assertValue(6L) //
.assertNoErrors() //
.awaitTerminalEvent();
}

/**
* Result set {@link com.datastax.driver.core.Row}s are converted to entities as they are emitted. Reactive pull and
* prefetch define the amount of fetched records.
*/
@Test
public void shouldPerformConversionBeforeResultProcessing() throws Exception {

CountDownLatch countDownLatch = new CountDownLatch(1);
public void shouldPerformConversionBeforeResultProcessing() {

repository.findAll() //
.doOnNext(System.out::println) //
.doOnEach(it -> countDownLatch.countDown()) //
.doOnError(throwable -> countDownLatch.countDown()) //
.subscribe();

countDownLatch.await();
.test() //
.awaitCount(4) //
.assertNoErrors() //
.awaitTerminalEvent();
}

/**
Expand All @@ -110,11 +103,11 @@ public void shouldPerformConversionBeforeResultProcessing() throws Exception {
@Test
public void shouldQueryDataWithQueryDerivation() {

List<Person> whites = repository.findByLastname("White") //
.toList() //
.blockingGet();

assertThat(whites).hasSize(2);
repository.findByLastname("White") //
.test() //
.awaitCount(2) //
.assertNoErrors() //
.awaitTerminalEvent();
}

/**
Expand All @@ -123,10 +116,11 @@ public void shouldQueryDataWithQueryDerivation() {
@Test
public void shouldQueryDataWithStringQuery() {

Person heisenberg = repository.findByFirstnameAndLastname("Walter", "White") //
.blockingGet();

assertThat(heisenberg).isNotNull();
repository.findByFirstnameAndLastname("Walter", "White") //
.test() //
.awaitCount(1) //
.assertNoErrors() //
.awaitTerminalEvent();
}

/**
Expand All @@ -135,11 +129,11 @@ public void shouldQueryDataWithStringQuery() {
@Test
public void shouldQueryDataWithDeferredQueryDerivation() {

List<Person> whites = repository.findByLastname(Single.just("White")) //
.toList() //
.blockingGet();

assertThat(whites).hasSize(2);
repository.findByLastname(Single.just("White")) //
.test() //
.awaitCount(2) //
.assertNoErrors() //
.awaitTerminalEvent();
}

/**
Expand All @@ -148,9 +142,10 @@ public void shouldQueryDataWithDeferredQueryDerivation() {
@Test
public void shouldQueryDataWithMixedDeferredQueryDerivation() {

Person heisenberg = repository.findByFirstnameAndLastname(Single.just("Walter"), "White") //
.blockingGet();

assertThat(heisenberg).isNotNull();
repository.findByFirstnameAndLastname(Single.just("Walter"), "White") //
.test() //
.awaitCount(1) //
.assertNoErrors() //
.awaitTerminalEvent();
}
}
8 changes: 7 additions & 1 deletion mongodb/reactive/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</properties>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
Expand All @@ -33,6 +33,12 @@
<artifactId>rxjava-reactive-streams</artifactId>
</dependency>

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Loading

0 comments on commit 69c2c2a

Please sign in to comment.