提问者:小点点

在 Spring 引导中为 catch 块添加代码覆盖率


使用< code>2.1.6 .版本

这是我的带有repo.save方法的serviceImpl类,在db字段重复的情况下,我们捕获异常并返回响应

@Service
public class CoreVoucherServiceImpl implements CoreVoucherService {

    @Override
    @Transactional(propagation = REQUIRED)
    public VoucherDTO createVoucher(VoucherDTO voucherDTO) {
        ... /* transforming DTO to Entity */
        try {
            voucherRepository.save(voucher);
        } catch (Exception e) {
            if (e.getCause() instanceof ConstraintViolationException) {
                throw new MyException(FIELD_NOT_UNIQUE, "title");
            }
            UB_LOGGER.debug("Error in create voucher", e);
            throw e;
        }
        voucherDTO.setId(voucher.getId());
        return voucherDTO;
    }
}

我无法为catch块添加代码覆盖率。我的测试类是

@SpringBootTest
@RunWith(SpringRunner.class)
public class CoreVoucherServiceTest {

    @Autowired
    private CoreVoucherService coreVoucherService;

    @MockBean
    private VoucherRepository voucherRepository;

    @Test
    // @Test(expected = MyException.class)
    public void createVoucherTest() {
        VoucherDTO dto = prepareCreateVoucher();
        when(voucherRepository.save(any())).thenThrow(Exception.class);
        coreVoucherService.createVoucher(dto);
    }
}

用上面的方法我得到了下面的错误

org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!
Invalid: java.lang.Exception

我如何抛出一个异常,其getCauseConstraintViolationException,因此所有行都包含在测试中


共3个答案

匿名用户

您必须在catch块中测试两个用例:

异常原因为< code > ConstraintViolationException 时

.thenThrow(new RuntimeException(new ConstraintViolationException("Field not Unique", null, "title")));

当异常原因不是< code > ConstraintViolationException 时

.thenThrow(new RuntimeException("oops"));

在这种情况下,@ExpectedException将是RuntimeException

匿名用户

您应该抛出ConstraintViolationException,因为save方法不会根据其方法定义save抛出任何选中的异常

when(voucherRepository.save(any()))
      .thenThrow(.ConstraintViolationException.class); 

匿名用户

还可以在Junit中用@Rule和ExpectedException测试异常。

@SpringBootTest
@RunWith(SpringRunner.class)
public class CoreVoucherServiceTest {

    @Autowired
    private CoreVoucherService coreVoucherService;

    @MockBean
    private VoucherRepository voucherRepository;

    @Rule
    public ExpectedException exceptionRule = ExpectedException.none();

    @Test
    // @Test(expected = MyException.class)
    public void createVoucherTest() {
        exceptionRule.expect(Exception.class); // Better if you specify specific Exception class that is going to be thrown.
        VoucherDTO dto = prepareCreateVoucher();
        when(voucherRepository.save(any())).thenThrow(Exception.class);
        coreVoucherService.createVoucher(dto);
    }
}