Jacoco 报告缺少分支,但这些分支已存在测试

问题描述 投票:0回答:1

我有一个带有 java 版本 21 的 Spring Boot maven 多模块项目,并使用 Jacoco 版本 0.8.11 进行代码覆盖。单元测试是使用groovy编写的。

我有这样的课:

package ********************;

import lombok.Getter;

import java.util.Arrays;

@Getter
public enum SomeEnum {
    VALUE1("some-value1"),

    VALUE2("some-value2"),

    VALUE3("some-value3");

    private final String value;


    private SomeEnum(String value) {
        this.value = value;
    }

    public static SomeEnum fromValue(String value) {
        if (value == null) {
            return null;
        }
        return Arrays.stream(values())
                .filter(someEnum -> someEnum.getValue().equals(value))
                .findFirst()
                .orElseThrow(() -> new IllegalArgumentException("Invalid input value"));
    }
}

这是 Groovy 测试:

package *****************************

import *********************.SomeEnum
import spock.lang.Specification

class SomeEnumTest extends Specification {

    def 'test1'(String s, SomeEnum expected) {
        when:
        var resp = SomeEnum.fromValue(s)
        then:
        resp == expected
        where:
        s || expected
        'some-value1' || SomeEnum.VALUE1
        'some-value2' || SomeEnum.VALUE2
        'some-value3' || SomeEnum.VALUE3
    }

    def 'test2'() {
        when:
        SomeEnum.fromValue('bs')
        then:
        thrown(IllegalArgumentException)
    }
}

在 jacoco 的结果中,我看到这部分没有被覆盖,但它的测试存在。涵盖了构造函数和枚举值。测试成功运行。有什么问题吗?

java jacoco
1个回答
0
投票

不幸的是,这是 JaCoCo 的一个已知限制。 JaCoCo 的工作原理是在代码的不同位置注入探针(在您的示例中,在

return
之前和之后)。如果 JVM 执行探测,JaCoCo 会假设该探测之前的任何代码都已被覆盖。然而,
return
throw
语句退出函数,并且永远不会到达
return
throw
语句之后的探测。因此,JaCoCo 假设
return
/
throw
尚未被覆盖。 JaCoCo 的 FAQ 有更多相关信息。

您的示例的一个特殊之处是,JaCoCo 通常至少会识别

return
语句的这种情况,因此将
return
语句标记为已覆盖,即使仅到达 return 语句之前的探测也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.