我从Mockito开始做单元测试。我已经看到了几个如何执行单元测试的例子,但它对我不起作用,因为当我传递对象来搜索它是否存在并修改它时,异常被抛出,测试被中断。
当这一行被执行时:BDDMockito.given(syndromeTypeServiceMock.modifySyndromeType(synTypeMock)).willReturn(synTypeMockAspect);它在服务中输入方法,当使用mock进行验证时,通过不去数据库查找记录,它返回null或空,并且下面的验证引发异常。我如何用Mockito验证这个异常,使它通过测试?
先谢了!
@ExtendWith(MockitoExtension.class)
public class SyndromeTypeServiceTest {
Logger LOGGER = LoggerFactory.getLogger(getClass());
@Mock
SyndromeTypeRepository syndromeTypeRepository;
@Mock
SyndromeTypeTransRepository syndromeTypeTransRepository;
@InjectMocks
SyndromeTypeServiceImpl syndromeTypeServiceMock;
@Test
public void test_modify_SyndromeType_when_synTransId_exist() throws PersistenceException {
LOGGER.info("test_modify_SyndromeType_when_synTransId_exist >>");
SyndromeType synTypeMock = SyndromeType.builder()
.synTypeId(10)
.synTypeName("Musculoesquelético.")
.lanCode("es")
.synTypeTransId(10)
.build();
SyndromeType synTypeMockEspect = SyndromeType.builder()
.synTypeId(10)
.synTypeName("Musculoesquelético.")
.lanCode("es")
.synTypeTransId(10)
.build();
BDDMockito.given(syndromeTypeServiceMock.modifySyndromeType(synTypeMock)).willReturn(synTypeMockEspect);
assertEquals(synTypeMock.getSynTypeTransId(), synTypeMockEspect.getSynTypeTransId());
assertEquals(synTypeMock.getSynTypeId(), synTypeMockEspect.getSynTypeId());
assertEquals(synTypeMock.getSynTypeName(), synTypeMockEspect.getSynTypeName());
LOGGER.info("<< test_modify_SyndromeType_when_synTransId_exist");
}
}
服务层
@Service
@Transactional
public class SyndromeTypeServiceImpl implements SyndromeTypeService {
Logger LOGGER = LoggerFactory.getLogger(getClass());
final SyndromeTypeRepository syndromeTypeRepository;
final SyndromeTypeTransRepository syndromeTypeTransRepository;
public SyndromeTypeServiceImpl(SyndromeTypeRepository syndromeTypeRepository,
SyndromeTypeTransRepository syndromeTypeTransRepository) {
this.syndromeTypeRepository = syndromeTypeRepository;
this.syndromeTypeTransRepository = syndromeTypeTransRepository;
}
@Override
public List<SyndromeType> renderSyndromeTypes(List<SyndromeTypeTransEntity> synTypesEtts){
LOGGER.info("Rendering SyndromeTypeEntity results");
List<SyndromeType> synTypes = new ArrayList<SyndromeType>(0);
if(null != synTypesEtts) {
synTypesEtts.stream()
.forEach(
s -> {
synTypes.add(
SyndromeType.builder()
.synTypeId(s.getSynTypeEtt().getSynTypeId())
.synTypeName(s.getSynTypeName())
.lanCode(s.getLanCodeEtt().getLanCode())
.synTypeTransId(s.getSynTypeTransId())
.build()
);
});
}
return synTypes;
}
@Override
public SyndromeType modifySyndromeType(SyndromeType synType) throws PersistenceException {
LOGGER.info("modifySyndromeType >>");
Optional<SyndromeTypeTransEntity> synTypeEtt = java.util.Optional.empty();
if(null != synType.getSynTypeTransId()) {
synTypeEtt = syndromeTypeTransRepository.findById(synType.getSynTypeTransId());
}
if(!synTypeEtt.isPresent() || synTypeEtt.isEmpty()) {
throw new PersistenceException(ErrorMessage.RECORD_NOT_EXIST.name());
}
SyndromeTypeTransEntity synTypeTrans = SyndromeTypeTransEntity.builder()
.lanCodeEtt(LanguageEntity.builder()
.lanCode(synType.getLanCode())
.build())
.synTypeName(synType.getSynTypeName())
.build();
synTypeTrans = syndromeTypeTransRepository.save(synTypeTrans);
List<SyndromeType> synTypesTO = this.renderSyndromeTypes(List.of(synTypeTrans));
SyndromeType synTypeTO = synTypesTO.isEmpty() ? null : synTypesTO.get(0);
LOGGER.info("<< modifySyndromeType");
return synTypeTO;
}
}
2条答案
按热度按时间dgiusagp1#
Mockito mock对象(使用
Mockito.mock
或@Mock
创建)默认情况下总是返回null
或空集合。如果你要求它们返回一个不同的值,你必须存根的方法。另一方面,
@InjectMocks
创建接口/类的 * 真实的 * 示例,并将模拟对象作为依赖项注入。一个真实的示例的方法不能被stub--而且这也没有意义,因为这是您通常希望在测试中使用的类。这意味着如果您想测试您的服务,您需要确保您调用的是真实的服务,并且它调用的任何方法都返回有用的值。
下面的代码块在 repository(不是服务)上调用
findById
,您已经为它创建了一个mock对象,但从未存根任何方法。仓库的方法可以在你的测试中被存根化如下:
第二次对仓库的调用也必须被存根化:
一个足够的存根实现可能只是返回参数本身:
在测试方法中设置了存根调用之后,必须调用类的 * 真实的 * 方法(如果不调用真实的方法,那么测试的是什么!?)
然后Assert返回的正确值:
或
khbbv19g2#
感谢@knittle,他已经能够纠正测试,最重要的是,对于要测试的方法中的每个动作,必须执行模拟。这是对测试的修改。