如何用 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
.
上调用任何方法
将测试视为具有三个部分很有用,通常称为 given、when 和 then:
- 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 测试这些案例可能会更简单。这将需要更少的设置(不需要模拟)并且不需要从响应中解压实体。
我有一个 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
.
将测试视为具有三个部分很有用,通常称为 given、when 和 then:
- 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 测试这些案例可能会更简单。这将需要更少的设置(不需要模拟)并且不需要从响应中解压实体。