Reactorにはユニットテスト用のヘルパーStepVerifier
が用意されています。
http://projectreactor.io/docs/core/release/reference/#testing
このStepVerifier
を使うことで、テスト中に、Flux
/Mono
をsubscribe
したりblock
したりしなくても、
ストリームデータの内容を検証できるようになります。
依存ライブラリの追加
reactor-test
を追加すれば利用可能です。
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
使い方
StepVerifier.create
にPublisher
に渡して、expectXxxx
メソッドで検証です。
以下は使用例です。
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
public class ReactorDojoTest {
ReactorDojo reactorDojo = new ReactorDojo();
@Test
public void identity() throws Exception {
Flux<String> input = Flux.just("hoge", "foo", "bar");
Flux<String> output = reactorDojo.identity(input);
StepVerifier
.create(output)
.expectNext("hoge", "foo", "bar")
.verifyComplete();
}
@Test
public void toUppercase() throws Exception {
Flux<String> input = Flux.just("hoge", "foo", "bar");
Flux<String> output = reactorDojo.toUppercase(input);
StepVerifier
.create(output)
.expectNext("HOGE", "FOO", "BAR")
.verifyComplete();
}
@Test
public void toOddNumbers() throws Exception {
Flux<Integer> input = Flux.just(1, 2, 3, 4, 5, 6, 7, 8, 9);
Flux<Integer> output = reactorDojo.oddNumbers(input);
StepVerifier
.create(output)
.expectNext(1, 3, 5, 7, 9)
.verifyComplete();
}
@Test
public void commaSplit() throws Exception {
Flux<String> input = Flux.just("aaa,bbb,", "ccc,ddddd,eee,", "ffff,g,", "hh,", "iiiii,jjj,");
Flux<String> output = reactorDojo.commaSplit(input);
StepVerifier
.create(output)
.expectNext("aaa", "bbb", "ccc", "ddddd", "eee", "ffff", "g", "hh", "iiiii", "jjj")
.verifyComplete();
}
}
Reactor脳トレ
では上記のテストをブラックボックステストとして、input
を受け取ってoutput
を返すメソッドを実装してみてください。
次の雛形を利用してください。
import reactor.core.publisher.Flux;
import java.util.stream.Collectors;
public class ReactorDojo {
public Flux<String> identity(Flux<String> input) {
return input;
}
public Flux<String> toUppercase(Flux<String> input) {
return input;
}
public Flux<Integer> oddNumbers(Flux<Integer> input) {
return input;
}
public Flux<String> commaSplit(Flux<String> input) {
return input;
}
}
プロジェクトも用意しましたので、実装したい方は利用してください。
https://github.com/making/reactor-dojo
このままテストを実行すると3件のテストが失敗します。
全て緑になるように実装してみてください。簡単ですね?
真のReactor脳トレ
上記の例はとても簡単でJava 8のStream APIの利用経験があれば、実装できると思います。 では通常のStream APIでは実現できない例を挙げます。
上記のcommaSplit
メソッドに対して次のテストケースも追加します。このテストも通るように実装してみてください。
@Test
public void commaSplitAdvanced() throws Exception {
Flux<String> input = Flux.just("aaa,bb", "b,ccc,ddddd,e", "ee,ff", "ff,g,hh,i", "i", "iii,jjj,");
Flux<String> output = reactorDojo.commaSplit(input);
StepVerifier
.create(output)
.expectNext("aaa", "bbb", "ccc", "ddddd", "eee", "ffff", "g", "hh", "iiiii", "jjj")
.verifyComplete();
}
テストデータは有限なストリームですが、実際はデータが続くこと想定して実装してください。 次のテストケースでも成功しますか?
@Test
public void commaSplitAdvancedInfinite() throws Exception {
Flux<String> input = Flux.just("aaa,bb", "b,ccc,ddddd,e", "ee,ff", "ff,g,hh,i", "i", "iii,jjj,").repeat();
Flux<String> output = reactorDojo.commaSplit(input);
StepVerifier
.create(output)
.expectNext("aaa", "bbb", "ccc", "ddddd", "eee", "ffff", "g", "hh", "iiiii", "jjj")
.expectNext("aaa", "bbb", "ccc", "ddddd", "eee", "ffff", "g", "hh", "iiiii", "jjj")
.expectNext("aaa", "bbb", "ccc", "ddddd", "eee", "ffff", "g", "hh", "iiiii", "jjj");
}
これはちょっと難しいかも。考えてみてください。
できた方はPull Requestを送ってみてください。