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

补充JoinQueryService测试用例以提升测试覆盖率至85%

补充JoinQueryService测试用例以提升测试覆盖率至85%

看了你的JoinQueryService代码和已有的测试用例,我发现还有几个关键场景没有覆盖到,这些正是导致你测试覆盖率没达标的主要原因。我整理了下面这些补充测试用例,覆盖了所有遗漏的分支和边界情况,应该能帮你把覆盖率提升到85%以上:

一、异常分支测试(两个字段都为空的场景)

这是你现有测试完全缺失的分支,两个方法都需要验证当empName和empEmail都为空时,是否正确抛出EmployeeDataNotFoundException:

getCrediProduct方法的异常测试

@Test(expected = EmployeeDataNotFoundException.class)
public void testGetCrediProduct_BothFieldsEmpty_ThrowsException() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "", "", "empAddress");
    
    // Run the test
    joinQueryServiceUnderTest.getCrediProduct(input);
}

deleteCreditProduct方法的异常测试

@Test(expected = EmployeeDataNotFoundException.class)
public void testDeleteCreditProduct_BothFieldsEmpty_ThrowsException() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "", "", "empAddress");
    
    // Run the test
    joinQueryServiceUnderTest.deleteCreditProduct(input);
}

二、单个字段分支的独立测试

你现有测试没有单独验证每个条件分支(只传姓名、只传邮箱),且验证逻辑有误(比如delete方法的测试同时验证了三个Repository方法,而一次调用只会走一个分支),下面是每个分支的独立测试:

getCrediProduct - 仅传入empName

@Test
public void testGetCrediProduct_OnlyEmpNameProvided() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "JohnDoe", "", "123 Street");
    final List<DeptEmpDto> expectedList = List.of(new DeptEmpDto("HR", "JohnDoe", "john@test.com", "123 Street"));
    
    when(mockEmployeeRepository.fetchEmpDeptDataInnerJoinByName("JohnDoe")).thenReturn(expectedList);
    
    // Run the test
    final List<DeptEmpDto> result = joinQueryServiceUnderTest.getCrediProduct(input);
    
    // Verify: 确保只调用了对应的Repository方法,其他方法从未被调用
    assertEquals(expectedList, result);
    verify(mockEmployeeRepository, times(1)).fetchEmpDeptDataInnerJoinByName("JohnDoe");
    verify(mockEmployeeRepository, never()).fetchEmpDeptDataInnerJoinByEmail(anyString());
    verify(mockEmployeeRepository, never()).fetchEmpDeptDataInnerJoin(anyString(), anyString());
}

getCrediProduct - 仅传入empEmail

@Test
public void testGetCrediProduct_OnlyEmpEmailProvided() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "", "jane@test.com", "456 Avenue");
    final List<DeptEmpDto> expectedList = List.of(new DeptEmpDto("Finance", "JaneSmith", "jane@test.com", "456 Avenue"));
    
    when(mockEmployeeRepository.fetchEmpDeptDataInnerJoinByEmail("jane@test.com")).thenReturn(expectedList);
    
    // Run the test
    final List<DeptEmpDto> result = joinQueryServiceUnderTest.getCrediProduct(input);
    
    // Verify
    assertEquals(expectedList, result);
    verify(mockEmployeeRepository, times(1)).fetchEmpDeptDataInnerJoinByEmail("jane@test.com");
    verify(mockEmployeeRepository, never()).fetchEmpDeptDataInnerJoinByName(anyString());
    verify(mockEmployeeRepository, never()).fetchEmpDeptDataInnerJoin(anyString(), anyString());
}

deleteCreditProduct - 仅传入empName

@Test
public void testDeleteCreditProduct_OnlyEmpNameProvided() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "JohnDoe", "", "123 Street");
    
    // Run the test
    final String result = joinQueryServiceUnderTest.deleteCreditProduct(input);
    
    // Verify
    assertEquals("Deleted Successfully", result);
    verify(mockEmployeeRepository, times(1)).deleteEmpDeptDataInnerJoinByName("JohnDoe");
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoinByEmail(anyString());
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoin(anyString(), anyString());
}

deleteCreditProduct - 仅传入empEmail

@Test
public void testDeleteCreditProduct_OnlyEmpEmailProvided() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "", "jane@test.com", "456 Avenue");
    
    // Run the test
    final String result = joinQueryServiceUnderTest.deleteCreditProduct(input);
    
    // Verify
    assertEquals("Deleted Successfully", result);
    verify(mockEmployeeRepository, times(1)).deleteEmpDeptDataInnerJoinByEmail("jane@test.com");
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoinByName(anyString());
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoin(anyString(), anyString());
}

deleteCreditProduct - 同时传入两个字段

@Test
public void testDeleteCreditProduct_BothFieldsProvided() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", "JohnDoe", "john@test.com", "123 Street");
    
    // Run the test
    final String result = joinQueryServiceUnderTest.deleteCreditProduct(input);
    
    // Verify
    assertEquals("Deleted Successfully", result);
    verify(mockEmployeeRepository, times(1)).deleteEmpDeptDataInnerJoin("JohnDoe", "john@test.com");
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoinByName(anyString());
    verify(mockEmployeeRepository, never()).deleteEmpDeptDataInnerJoinByEmail(anyString());
}

三、边界场景测试

验证字段为空格的情况(因为isEmpty()判断的是字符串长度为0,空格字符串的isEmpty()返回false,会走对应的分支):

@Test
public void testGetCrediProduct_EmpNameIsSpace() {
    // Setup
    final DeptEmpDto input = new DeptEmpDto("empDept", " ", "", "123 Street");
    final List<DeptEmpDto> expectedList = List.of(new DeptEmpDto("HR", " ", "space@test.com", "123 Street"));
    
    when(mockEmployeeRepository.fetchEmpDeptDataInnerJoinByName(" ")).thenReturn(expectedList);
    
    // Run the test
    final List<DeptEmpDto> result = joinQueryServiceUnderTest.getCrediProduct(input);
    
    // Verify
    assertEquals(expectedList, result);
    verify(mockEmployeeRepository, times(1)).fetchEmpDeptDataInnerJoinByName(" ");
}

添加完这些测试用例后,你可以重新运行Sonar扫描,应该能覆盖所有代码分支,把覆盖率提升到85%以上。

备注:内容来源于stack exchange,提问作者LMReddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:34:27