如何用 java 和 Junit 完全填充我的方法的覆盖范围?

How to tetsing completely fill the coverage of my method with java and Junit?

我有一个 Java 查询数据库和 returns 列表的服务,在我的服务中我调用了我的 Util 的 validacionCampos() 方法class,此 class 验证我的服务列表的字段是否具有空值或为 0 值设置为 0.000

我的目标是拥有一个涵盖所有服务方法和 util class 验证的测试用例。 我做了一个测试 clase 但它根本不起作用,因为 sonarqube 工具说它没有完全覆盖并指向 util class 的 if 行,我制作了两种方法,一种设置空值,另一种方法设置值 0 ,但我认为这是错误的或什么都不做

谁能帮帮我,测试用例是如何完成的,才能进入服务,有用class,覆盖面很全?

ServiceImpl Class

@Override
public ResponseEntity<?> consultarReportes(Integer fechaInicio, Integer fechaFin) throws Exception {
    Map<String, Object> response = new HashMap<>();
    List<EntityDa> consultarReporte = new ArrayList<EntityDa>();
    try {
        consultarReporte = bitacoraRepository
                .consultarBitacoras(fechaInicio, fechaFin);
        reporteUtil.validacionCampos(consultarReporte);

    } catch (Exception e) {
        LOGGER.error("An error ocurred looking for Entity Data");
        response.put("success", false);
        response.put("error", e.getMessage());
        return new ResponseEntity<Map<String, Object>>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    response.put("success", true);
    response.put("data", consultarReporte);
    return new ResponseEntity<>(response, HttpStatus.OK);
}

实用程序class

private static final String DECIMAL = "0.0000";

        public List<EntityDa> validacionCampos(List<EntityDa> lista) {
        for (EntityDa details : lista) {
            if (details.getRango() == null || details.getRango().equals("0")) {
                details.setRango(DECIMAL);
            }
            if (details.getPrima() == null || details.getPrima().equals("0")) {
                details.setPrima(DECIMAL);
            }
        }
        return lista;
        }

测试class

@Mock
BitacoraRepository bitacoraRepository;

@Test
void testExitoValidaNullos() throws Exception {
    EntityDa entity = new EntityDa();
    entity.setRango(null);
    entity.setPrima(null);
    
    List<EntityDa> list = new ArrayList<>();
    list.add(entity);
    when(bitacoraRepository.consultarBitacoras("20220112", "20220112")).thenReturn(list);
}

@Test
void testExitoValidaVacios() throws Exception {
    EntityDa entity = new EntityDa();
    entity.setRango("0");
    entity.setPrima("0");
    
    List<EntityDa> list = new ArrayList<>();
    list.add(entity);
    when(bitacoraRepository.consultarBitacoras("20220112", "20220112")).thenReturn(list);
}

更新

我按照你的例子实现了它并且它保持这样因为 IDE 添加了一个 CAST 到 ResponseEntity> 因为我的服务是已声明 ResponseEntity

@Test
    public void testExitoValidaNullos() throws Exception {
        // Given a repository containing an entity with "rango" and "prima" set to null
        EntityDa entity = new EntityDa();
        entity.setRango(null);
        entity.setPrima(null);

        List<EntityDa> list = new ArrayList<>();
        list.add(entity);
        when(bitacoraRepository.consultarBitacoras("20220112", "20220112")).thenReturn(list);

        // When consultarReportes is called
        ResponseEntity<Map<String, Object>> response = (ResponseEntity<Map<String, Object>> serviceImpl.consultarReportes("20220112", "20220112");


        // Then the returned entity should have "rango" and "prima" set to "0.0000"
        EntityDa returnedEntity = ((List<EntityDa>) response.getBody().get("data")).get(0);
        assertEquals("0.0000", returnedEntity.getRango());
        assertEquals("0.0000", returnedEntity.getPrima());
    }

我运行测试并发送这个:

org.opentest4j.AssertionFailedError:预期:<0.0000> 但为:<41831.3>

显然它没有将设置设为空

更新

直接测试实用程序 CLASS 我在行 claseUtil.validacionCampos(list);

中收到错误 NullPointerException
    @AutoConfigureMockMvc
    @SpringBootTest
    public class ClaseTest {
    
    @Autowired
    ClaseUtil claseUtil;
    
    
    @Test
    public void prepare() throws Exception {
        EntityDa entity = new EntityDa();
        entity.setRango(null);
        entity.setPrima(null);

        List<EntityDa> list = new ArrayList<EntityDa>();
        list.add(entity);

        claseUtil.validacionCampos(list);

    }
    }

SonarQube 报告没有覆盖这些行,因为这些测试实际上并不执行此代码。他们执行一些设置,但不在 ServiceImpl.

上调用任何方法

将测试视为具有三个部分很有用,通常称为 givenwhenthen:

  • Given表示测试用例的上下文或环境
  • 描述了所采取的行动-正在测试的操作
  • 然后描述了预期或预期的结果

使用书面语言以这种格式写出需求,然后将书面需求翻译成代码可能会有所帮助。

例如,我可能会写这些测试用例的需求(英文):

  • 给定一个包含“rango”为null或“0”的实体的存储库,
  • 调用consultarReportes时,
  • 然后 returned 实体应该将“rango”设置为“0.0000”

并且:

  • 给定一个存储库,其中包含一个“prima”为null或“0”的实体,
  • 调用consultarReportes时,
  • 然后 returned 实体应该将“prima”设置为“0.0000”

代码方面:

  • Given 通常转化为设置数据,有时是模拟。
  • 是调用被测方法时
  • Then 通常是关于 return 值或受该方法影响的其他状态的断言。它也可以是对模拟对象调用的方法的验证,特别是当您测试一个没有 return 值且只执行副作用的方法时。

在这种情况下,测试可能如下所示:

@Test
public void testExitoValidaNullos() throws Exception {
    // Given a repository containing an entity with "rango" and "prima" set to null
    EntityDa entity = new EntityDa();
    entity.setRango(null);
    entity.setPrima(null);

    List<EntityDa> list = new ArrayList<>();
    list.add(entity);
    BitacoraRepository bitacoraRepository = mock(BitacoraRepository.class);
    when(bitacoraRepository.consultarBitacoras("20220112", "20220112")).thenReturn(list);

    // When consultarReportes is called
    ServiceImpl serviceImpl = new ServiceImpl(bitacoraRepository);
    ResponseEntity<Map<String, Object>> response = serviceImpl.consultarReportes("20220112", "20220112");

    // Then the returned entity should have "rango" and "prima" set to "0.0000"
    EntityDa returnedEntity = ((List<EntityDa>) response.getBody().get("data")).get(0);
    assertEquals("0.0000", returnedEntity.getRango());
    assertEquals("0.0000", returnedEntity.getPrima());
}

对 testExitoValidaVacios 的更改与此类似。

(我对提供的代码进行了一些其他更改以使其能够编译。)

为了完全涵盖所有可能性,您还需要为这些字段设置为其他值时编写测试用例。您可能还想通过存根 bitacoraRepository.consultarBitacoras 来抛出异常来测试异常处理程序。

请注意,直接针对 Util class 测试这些案例可能会更简单。这将需要更少的设置(不需要模拟)并且不需要从响应中解压实体。