【问题标题】:Junit has partially covering the code for webclient's doOnError methodJunit 已经部分覆盖了 webclient 的 doOnError 方法的代码
【发布时间】:2022-01-17 02:34:37
【问题描述】:

一个抽象类包含一个使用 webclient 进行休息调用的通用方法 Webclinet 构建通过构造函数自动连接
下面给出了抽象类结构及其对应的测试类

    @Component
    public abstract class client{
    
       @Autowired WebClient.Builder builder;
    
      public <T,R> Mono<R> callApi(T req,Class<R> resp,String mode) {
        return WebClient.builder()
            .baseUrl("http://localhost:8080")
            .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
            .build()
            .post()
            .uri("/v1/student")
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .bodyValue(req)
            .retrieve()
            .bodyToMono(resp)
            .doOnError(err->handleError(err,mode));
      }
    
      private void handleError(Throwable err,String mode) {
        if(mode){
          throw new CustomExp1();
        }
        throw new CustomExp2();
      }
    }
On Error scenario Global Controller advise will catch the exception and return the response Entity based upon the CustomExp throw.

Junit- 测试抽象类的apiCall的代码如下, 创建示例类并扩展抽象类并创建示例类的 spy mock 以调用抽象类方法。

  public class MainClient{
  
  public static class MainClient extends client(){
  public MainClient(WebClient.builder webClientBuilder)
  super(webClientBuilder)
    }

      @InjectMock
      @spy
      MainClient spyMainClient

      @Mock
      private WebClient.builder webClientBuilder=WebClient.builder();
  
      @Mock
      private WebClient buildMock;
  
      @Mock
      private WebClient.RequestBodyUriSpec uriMock;   
  
  
      @Mock
      private WebClient.RequestBodySpec bodySpecMock;
  
      
      @Mock
      private WebClient.RequestHeadersSpec headersSpecMock;
      
      
      @Mock
      private WebClient.ResponseSpec responseSpecMock;
  
     @Mock
      private Mono<Post> responseMock;
  
  @Test
  callTestError(){
  Mono<Post> response= Mono.error(new Throwable("Error"));
  
  when(webClientBuilder).thenReturn(buildMock);
  when(buildMock.post()).thenReturn(uriMock);      
  when(uriMock.uri(anyString())).thenReturn(bodySpecMock);
  when(bodySpecMock.contentType(MediaType.JSON)).thenReturn(bodySpecMock);
  doReturn(headersSpecMock).when(bodySpecMock).bodyValue(any());
  doReturn(responseSpecMock).when(headersSpecMock).retrieve();
  when(responseSpecMock.bodyToMono(Post.class).thenReturn(responseMock));
  when(responseMock.doOnError(any())).thenReturn(response)
  
  spyMainClient.callApi(new Req(),Post.class,true);
  
  }
  }
when executing the test case, it's completing successfully, but when i look at jacoco report  .doOnError(err->handleError(err,mode)); section of webclient is partially completed.

谁能帮我解决问题

【问题讨论】:

  • 如果我将 doOnerror 方法更改为 doOnError(err->{ if(mode){ throw new CustomExp1(); } throw new CustomExp2(); }),上面的代码正在工作并且覆盖率为 100% ;
  • 如果我在 doOnError 中添加单独的方法,仍然不确定为什么代码覆盖率是部分的

标签: java spring spring-boot junit webclient


【解决方案1】:

我认为 doOnError 是一个异常路径,只有在失败时才会执行。所以你应该对失败场景进行另一次测试,在这种情况下你应该在某个时候失败,比如:

 when(bodySpecMock.contentType(MediaType.JSON)).thenThrow(new RuntimeException());

错误流应该选择这个失败并执行 doOnError 块

【讨论】:

    猜你喜欢
    • 2015-05-23
    • 2016-05-11
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多