【问题标题】:Jacoco doesn't detect interfacesJacoco 没有检测到接口
【发布时间】:2019-05-08 23:07:16
【问题描述】:

我已配置 Jacoco,以便它在单元测试运行时生成覆盖率报告。

<plugin>
            <groupId>org.jacoco</groupId>
            <artifactId>jacoco-maven-plugin</artifactId>
            <version>0.8.2</version>
            <executions>
                <execution>
                    <id>unit-test-prepare-agent</id>
                    <goals>
                        <goal>prepare-agent</goal>
                    </goals>
                    <configuration>
                        <propertyName>surefireArgLine</propertyName>
                        <destFile>${jacoco.report.directory}/jacoco-ut.exec</destFile>
                    </configuration>
                </execution>
                <execution>
                    <id>unit-test-report</id>
                    <phase>test</phase>
                    <goals>
                        <goal>report</goal>
                    </goals>
                    <configuration>
                        <dataFile>${jacoco.report.directory}/jacoco-ut.exec</dataFile>
                        <outputDirectory>${jacoco.report.directory}/jacoco-ut</outputDirectory>
                    </configuration>
                </execution>
    </executions>
</plugin>

但由于某种原因,它跳过了项目的 dao 包,其中包含 Spring Data Jpa 存储库接口。

例如如下界面:

import com.shaunyl.website.dao;

public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {

    @Query(value = "SELECT p FROM Product p",
            countQuery = "SELECT COUNT(p) FROM Product p")
    Page<Product> findAll(Pageable pageable);
}

有以下测试:

@RunWith(SpringRunner.class)
@DataJpaTest
public class ProductRepositoryTests {

    private static final int INVENTORY_SIZE = 5;

    @Autowired
    ProductRepository productRepository;

    private Category[] categories;

    private List<Product> inventory;

    @Before
    public void setUp() {
        inventory = productRepository.saveAll(products(INVENTORY_SIZE));
        categories = inventory.stream().map(Product::getCategory).toArray(Category[]::new);
    }

@Test
public void shouldRetrieveOnePageOfProducts() {
    // given
    int PAGE = 0;
    int SIZE = 20;
    Pageable pageable = newUnsortedPage(PAGE, SIZE);

    // when
    Page<Product> products = productRepository.findAll(pageable);

    // then
    assertThat(products.getNumber()).isEqualTo(PAGE);
    assertThat(products.getNumberOfElements()).isEqualTo(INVENTORY_SIZE);
    assertThat(products)
            .as("categories are eagerly fetched")
            .extracting(Product::getCategory)
            .containsExactlyInAnyOrder(categories);
 }
}

但是在 Jacoco 报告中,dao 包被跳过了。 我相信这是因为目标类是一个接口,但我不确定。

您知道可能是什么问题,以及如何解决它吗?

【问题讨论】:

    标签: java spring-boot junit spring-data-jpa jacoco


    【解决方案1】:

    JaCoCo 测量可执行的 Java 代码。在你的界面中

    public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
    
        @Query(value = "SELECT p FROM Product p",
                countQuery = "SELECT COUNT(p) FROM Product p")
        Page<Product> findAll(Pageable pageable);
    }
    

    没有可执行的 Java 代码,只有使用常量的方法声明和注解。

    这在JaCoCo FAQ中也有解释:

    为什么覆盖率报告中没有显示抽象方法?

    抽象方法不包含代码,因此无法评估代码覆盖率。事实上,实现这些方法的子类记录了代码覆盖率。这同样适用于接口中的非默认方法。

    【讨论】:

    • 但是如果你在 ProductRepository 中创建一个默认方法,Jacoco 会测量它的覆盖率吗?它不适合我。
    • 前进的最佳方式是什么?将该目录设置为被 jacoco 覆盖率报告忽略?忍受在实际有测试覆盖时它没有显示测试覆盖的事实吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2017-02-05
    相关资源
    最近更新 更多