如何编写JUnit测试覆盖控制器if语句,提升SonarQube测试覆盖率
问题根源
你当前的测试代码没有为authentication != null的场景构造有效数据:要覆盖if内的代码,需要在调用接口前主动向SecurityContextHolder中存入一个非空的Authentication实例,同时需要Mock userService的findUserByLogin方法的返回,避免运行时报空指针。
修正后的测试代码示例
假设你使用JUnit+Mockito栈进行测试,修正后的代码如下:
import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import static org.mockito.Mockito.*; // 测试类内代码 @Mock private UserService userService; @Mock private Authentication authentication; @InjectMocks private UserController userController; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); } // 测试if分支为true的场景,覆盖if块内两行代码 @Test void getAllInformationAboutUser_WithAuthentication_ReturnUser() { // 1. 模拟认证信息返回值 String testLogin = "testUser"; when(authentication.getName()).thenReturn(testLogin); // 2. 把模拟的认证实例塞入安全上下文 SecurityContext securityContext = mock(SecurityContext.class); when(securityContext.getAuthentication()).thenReturn(authentication); SecurityContextHolder.setContext(securityContext); // 3. 模拟userService查询返回 Utilisateur mockUser = new Utilisateur(); when(userService.findUserByLogin(testLogin)).thenReturn(mockUser); // 4. 调用目标接口 ResponseEntity<Utilisateur> response = userController.getAllInformationAboutUser(); // 5. 结果验证 assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(mockUser, response.getBody()); verify(userService, times(1)).findUserByLogin(testLogin); // 测试结束清理上下文,避免影响其他用例 SecurityContextHolder.clearContext(); } // 测试if分支为false的场景,覆盖认证为空的逻辑 @Test void getAllInformationAboutUser_WithoutAuthentication_ReturnNull() { // 直接清空上下文,保证authentication为null SecurityContextHolder.clearContext(); ResponseEntity<Utilisateur> response = userController.getAllInformationAboutUser(); assertEquals(HttpStatus.OK, response.getStatusCode()); assertNull(response.getBody()); // 验证未调用userService方法 verify(userService, never()).findUserByLogin(any()); }
覆盖率验证说明
两个测试用例分别覆盖了authentication != null的true和false两个分支,运行测试后SonarQube即可识别到if块内的两行代码已被覆盖。
内容的提问来源于stack exchange,提问作者Mohamed Dhia
相关产品推荐
相关产品推荐

