iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
Software Development

從零開始Reactive Programming- Spring系列 第 18

[Day 17] Reactive Programming - Reactor Test(StepVerifier)

  • 分享至 

  • xImage
  •  

前言

在之前的Reactor相關範例中,如果需要測試結果是否符合預期,都必須要透過System.out.println來印出結果人工檢視,有時候還必須加上Thread.sleep()來輔助,就算是這樣你都能接受,正式專案通常都有ci/cd來跑測試,這時候總不能還是透過人工去看console,好在Reactor在測試方面也有提供方便的工具給開發者。

StepVerifier

提供了聲明式的方式來做驗證,預期的事件或是下一個傳遞的值甚至連時間都可以控制。來看一下官方提供的範例:

首先是一個appendBoomError(),將傳入的Flux綁上一個內含Error,覺得這個命名很傳神,就是包裹炸彈一樣。
StepVerifier透過builder的方式,在create內傳入需要驗證的publisherexpectNext就是onNext,預期下一個data是否符合,也能夠預期錯誤發生,最後verify就是像subscribe一樣,當作一個啟動開始測試。

public <T> Flux<T> appendBoomError(Flux<T> source) {
  return source.concatWith(Mono.error(new IllegalArgumentException("boom")));
}

@Test
public void testAppendBoomError() {
  Flux<String> source = Flux.just("package1", "package2");

  StepVerifier.create(
          appendBoomError(source))
      .expectNext("package1")
      .expectNext("package2")
      .expectErrorMessage("boom")
      .verify();
}

簡單條列一下常用的expect

  1. expectNext:下一個item與傳入的相同。
  2. expectNextMatches(Predicate):比較複雜的判斷可以傳入Predicate
  3. assertNext(Consumer):直接傳入assertions
  4. expectNextCount(long):在下一個訊號之前的item數量
  5. expectNextSequence(Iterable):一次比對多個item

因為error&complete都是終結(terminal)訊號,也就是之後不會再有後續動作,所以可以與verify結合

  1. verifyComplete():publisher結束,傳入已完成的訊號(completion signal)
  2. verifyError(): publisher結束,但是因為有錯誤發生(unspecified error)
  3. verifyErrorMessage():多加上判斷message
//DefaultStepVerifierBuilder.java Source code
@Override
public Duration verifyError() {
 return expectError().verify();
}
@Override 
public Duration verifyComplete() { 
    return expectComplete().verify(); 
}
@Override 
public Duration verifyErrorMessage(String errorMessage) { 
    return expectErrorMessage(errorMessage).verify(); 
}

最後一個準備一個起始為3總數7個的Flux,透過上面介紹expectNextSequence一次比對五個item,下一個數字8刻意用Predicate判斷,expectNextCount我自己有點難懂,直到實際觀察他的行為才知道比較像是到下一個expect之前還有的數量,在這邊已經有6個item了,所以只會剩下一個而已,最後就是使用verifyComplete結合expectComplete &verify

@Test
public void verify(){
  Flux<Integer> integers = Flux.range(3,7);

  StepVerifier.create(integers)
      .expectNextSequence(Arrays.asList(3,4,5,6,7))
      .expectNextMatches(d -> (d / 2 ) == 4)
      .expectNextCount(1)
      .verifyComplete();
}

結語

如果想要更多的練習,有找到一個很棒的resource,reactor 官方github上的hands-on,裡面有非常多Test的範例。

資料來源


上一篇
[Day 16] Reactive Programming -Reactor(ConnectableFlux)
下一篇
[Day 18] Reactive Programming - Reactor Test(VirtualTime)
系列文
從零開始Reactive Programming- Spring32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言