You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot项目中Jacoco无法更新MockMvc测试的代码覆盖率问题

解决Jacoco未统计MockMvc测试代码覆盖率的问题

针对你遇到的Jacoco不统计MockMvc测试覆盖率的问题,结合你的代码和配置,我整理了几个关键排查点和解决方案:

1. 优先排查:请求路径是否真的命中Controller

你的测试请求路径是/gateway/v1/{thing}/{thing2},但看你给出的LegacyController的@GetMapping只有/{thing}/{thing2},如果你的Controller类上没有添加@RequestMapping("/gateway/v1")注解的话,这个请求根本没打到Controller方法里!这是最常见的导致覆盖率无变化的原因——测试看似通过,但实际没执行到目标代码。

解决:

  • 确认Controller类上的@RequestMapping路径,确保测试的请求路径和Controller的路径完全匹配;
  • 可以在Controller的doSomeThing方法里加一行日志或者断点,验证测试是否真的进入了该方法。

2. 优化测试类的注解配置

你当前用了@SpringBootTest + @AutoConfigureMockMvc + @WebAppConfiguration,这种全量上下文启动的方式不仅重,还可能导致Jacoco统计异常。推荐用专门针对Controller层的@WebMvcTest注解:

修改后的测试类:

@RunWith(SpringRunner.class)
@WebMvcTest(LegacyController.class) // 仅加载Controller相关的上下文
@ActiveProfiles("test")
public class LegacyControllerTest {
    @Autowired
    private MockMvc mockMvc; // 自动配置好的MockMvc,无需手动初始化

    @MockBean
    private LegacyService legacyService;

    @Test
    public void givenGetJson_WhenOffsetPageIsPresent_ThenReturnsCreated() throws Exception {
        Mockito.doReturn(new ResponseEntity<>("OK", HttpStatus.CREATED))
               .when(legacyService).crud(
                    Mockito.anyString(), Mockito.anyString(), 
                    Mockito.any(), Mockito.anyString(), 
                    Mockito.anyString(), Mockito.any(), 
                    Mockito.anyString()
                );
        mockMvc.perform(MockMvcRequestBuilders
                .get("/gateway/v1/{thing}/{thing2}", "value-thing", "value-thing2")
                .header("Content-Type", "application/json")
                .header("Header1", "Header1 value")
                .queryParam("OtherThing", "OtherThing value")
                .queryParam("OtherThing2", "OtherThing2 Value")
                .content("A BODY GOES HERE"))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isCreated()); // 注意Controller标注的是CREATED而非OK
    }
}

另外注意:你的Controller方法标注了@ResponseStatus(value = HttpStatus.CREATED),所以测试里的isOk()应该改成isCreated(),避免逻辑不一致。

3. 检查Jacoco插件的执行配置

你的Jacoco配置里,prepare-agent没有指定执行阶段,可能导致测试运行时代理没生效,无法生成覆盖率数据:

修改Jacoco插件的executions配置,明确绑定阶段并升级到稳定版:

<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.10</version> <!-- 升级到最新稳定版,兼容性更好 -->
    <configuration>
        <excludes>
            <exclude>**/constant/*</exclude>
            <exclude>**/dto/*</exclude>
            <exclude>**/enuns/*</exclude>
            <exclude>**/exception/*</exclude>
            <exclude>**/ApiApplication.class</exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>jacoco-prepare-agent</id>
            <phase>process-test-classes</phase> <!-- 明确在测试类处理后执行 -->
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>generate-code-coverage-report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>

4. 验证覆盖率数据文件是否生成

运行mvn clean test后,检查target目录下是否生成了jacoco.exec文件:

  • 如果没有,说明Jacoco的prepare-agent没生效,需要检查Maven插件的执行顺序,或者有没有其他插件干扰了Jacoco的代理;
  • 如果有,再运行mvn jacoco:report,然后查看target/site/jacoco下的HTML报告,确认是否有LegacyController的统计数据。

5. 排除其他可能的干扰

  • 确认你的Maven命令是正确的:推荐用mvn clean verify,这个命令会自动运行测试并生成覆盖率报告;
  • 检查Jacoco的exclude规则,确保没有误排除LegacyController所在的包;
  • 如果你用了Lombok,确保Jacoco能正确处理Lombok生成的代码(你的Spring Boot插件已经排除了Lombok,这部分没问题)。

内容的提问来源于stack exchange,提问作者Vitor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 19:08:14