当我们使用 Jacoco 覆盖工具在 Jenkins 上运行测试时,在 IDE 上本地运行的两个测试在 Jenkins 上失败了。
詹金斯堆栈跟踪
java.lang.NullPointerException: formatter
at java.util.Objects.requireNonNull(Objects.java:228)
at java.time.LocalDateTime.format(LocalDateTime.java:1751)
at valid.package.MyUtils.generateReferenceId(MyUtils.java:356)
测试类
public class MyUtils{
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyyyHHmmss");
//method under test
public static String generateReferenceId(StationState stationState) {
StringBuilder referenceId = new StringBuilder();
referenceId.append(String.format("%04d", stationState.getLocationId()));
referenceId.append(String.format("%06d", stationState.getStoreNbr()));
referenceId.append(String.format("%02d", stationState.getSessionId()));
referenceId.append(LocalDateTime.now().format(formatter)); //null was found here - line 356
return referenceId.toString();
}
测试
@RunWith(PowerMockRunner.class)
@PrepareForTest({
MyUtils.class
})
class MyUtilsTest{
@Test
public void generateReferenceId_whenGenerate_shouldReturnNotNull() {
//given
//when
String referenceId = MyUtils.generateReferenceId(stationState);
//then
// assertions
}
第二个测试方法在单独的类中,并且在不同的模式旁边看起来相同。
private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);
所以没有理由把它放在这里。所以:
我想知道 DateTimeFormatter.ofPattern(..) 如何为私有静态最终返回 null?
您是否认为这是因为 PowerMockito 与 Jacoco on-the-fly 仪器 PowerMockito 与 Jacoco 一起使用时会导致问题。如上述链接所述,我们正在发布降低的覆盖率。
当我内联
私有静态最终 DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT);
到 generateReferenceId() 方法
referenceId.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("ddMMyyyyHHmmss")));
对 Jenkins 的测试不再抛出 NPE。
环境细节:
本地环境:Java 版本 1.8.0.271,Win 10 操作系统,国家 PL
詹金斯版本:
[java] [echo] * Run By: jenkins on Wednesday, December 9, 2020 11:07:40 AM UTC
[java] [echo] * JVM: Oracle Corporation v25.231-b11
[java] [echo] * OS: Linux amd64 v4.14.203-156.332.amzn2.x86_64
Jenkins 在英国的 AWS 上。