简体   繁体   English

如何在 Jacoco 代码覆盖率中忽略 Lombok 的@SneakyThrows?

[英]How to ignore @SneakyThrows of Lombok in Jacoco code coverage?

I use JaCOCO to see code coverage (and use the Intellij plugin for it).我使用 JaCOCO 查看代码覆盖率(并使用 Intellij 插件)。 I have @SneakyThrows of lombok on my code.我的代码上有@SneakyThrows of lombok。 Since @SneakyThrows does nothing but converting a checked exception to a unchecked exception, I hope it does not affect the code coverage.由于@SneakyThrows 只会将已检查的异常转换为未检查的异常,因此我希望它不会影响代码覆盖率。

However, it seems that it drops the code coverage:但是,它似乎降低了代码覆盖率:

I have tried to add lombok.addLombokGeneratedAnnotation = true to my lombok.config , but no use.我试图将lombok.addLombokGeneratedAnnotation = true添加到我的lombok.config ,但没有用。

Thanks for any suggestions!感谢您的任何建议!

You can't ignore a certain code path, jacoco has no support for that (neither it can ignore a method).你不能忽略某个代码路径,jacoco 不支持它(它也不能忽略一个方法)。 Its unit of measure, for a lack of better term, is a .class file.由于缺乏更好的术语,它的度量单位是.class文件。 Since jacoco looks at the .class file, that is generated after lombok processor kicks in, for it - you simply have path that is un-tested.由于 jacoco 查看.class文件,该文件是在 lombok 处理器启动生成的,因此您只需拥有未经测试的路径。

In simpler words, jacoco sees your file like it never had lombok annotations.简而言之, jacoco看到您的文件就像它从未有过 lombok 注释一样。 So you can't "exclude" an annotation.所以你不能“排除”注释。 I feel your pain - we have modules where people have enforced a very high number of coverage, and these catch blocks are un-tested, almost all the time.我感受到了你的痛苦——我们有一些模块,人们强制执行了非常多的覆盖率,而这些 catch 块几乎一直都未经测试。

Adding @Generated with lombok.addLombokGeneratedAnnotation = true will only work for Lombok annotations that generate whole methods.使用lombok.addLombokGeneratedAnnotation = true添加@Generated仅适用于生成整个方法的 Lombok 注释。 However, @SneakyThrows will only add a try-catch block around the code inside of the annotated method.但是, @SneakyThrows只会在带注释的方法内部的代码周围添加一个try-catch块。

For example if you have following method and want to sneaky-throw the InterruptedException from Thread::sleep :例如,如果您有以下方法并想从Thread::sleep偷偷抛出InterruptedException

package com.example;

import lombok.SneakyThrows;

public class Example {

  @SneakyThrows
  public void someMethod() {
    System.out.println("This method does a few things");
    System.out.println("Like counting to 10");
    for (int i = 0; i < 10; i++) {
      System.out.println(i);
    }
    System.out.println("And waiting a second");
    Thread.sleep(1000);
  }
}

The generated code would look like this:生成的代码如下所示:

package com.example;

public class Example {

  public void someMethod() {
    try {
      System.out.println("This method does a few things");
      System.out.println("Like counting to 10");

      for (int i = 0; i < 10; ++i) {
        System.out.println(i);
      }

      System.out.println("And waiting a second");
      Thread.sleep(1000L);
    } catch (Throwable e) {
      throw e;
    }
  }
}

You actually only want to ignore the try-catch in the coverage check, not the whole method, so if Lombok added @Generated to the whole method you will ignore more coverage than intended.您实际上只想在覆盖检查中忽略try-catch ,而不是整个方法,因此如果 Lombok 在整个方法中添加@Generated您将忽略比预期更多的覆盖。

What you could do, is extracting the code that throws a checked exception to a new method and add both @Generated and @SneakyThrows .您可以做的是提取向新方法抛出检查异常的代码并添加@Generated@SneakyThrows

package com.example;

import lombok.Generated;
import lombok.SneakyThrows;

public class Example {

  public void someMethod() {
    System.out.println("This method does a few things");
    System.out.println("Like counting to 10");
    for (int i = 0; i < 10; i++) {
      System.out.println(i);
    }
    System.out.println("And waiting a second");
    waitOneSecond();
  }
  
  @Generated
  @SneakyThrows
  private void waitOneSecond() {
    Thread.sleep(1000);
  }
}

My solution on this is to attempt to mock objectMapper to throw an unchecked exception(eg: RuntimeException) then the code flow will jump inside to catch block(generated by Lombok) and @SneakyThrows will be covered.我对此的解决方案是尝试模拟objectMapper以引发未经检查的异常(例如:RuntimeException),然后代码流将跳转到内部以捕获块(由 Lombok 生成)并且将覆盖 @SneakyThrows。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM