spring-boot - 使用 Mockito 模拟 Spring Boot 存储库删除调用在 get() 上抛出 java.util.NoSuchElementException
问题描述
我是 Spring Boot 和 Mockito 的新手,在我的服务测试中模拟存储库调用时遇到问题。
我有一个“删除”服务方法调用,如下所示,我试图通过模拟存储库调用来使用 Mockito 进行测试:
public interface IEntityTypeService {
public EntityType getById(long id);
public EntityType getByName(String name);
public List<EntityType> getAll();
public void update(EntityType entityType);
public void delete(long id);
public boolean add(EntityType entityType);
}
@Service
public class EntityTypeServiceImpl implements IEntityTypeService {
@Autowired
private EntityTypeRepository entityTypeRepository;
@Override
public void delete(long id) {
entityTypeRepository.delete(getById(id));
}
@Override
public EntityType getById(long id) {
return entityTypeRepository.findById(id).get();
}
....implementation of other methods from the interface
}
我的存储库如下所示:
@RepositoryRestResource
public interface EntityTypeRepository extends LookupObjectRepository<EntityType> {
}
我没有在存储库中实现任何方法,因为我让 Spring Boot 为我连接它。
我的测试如下:
@RunWith(SpringRunner.class)
public class EntityTypeServiceTest {
@TestConfiguration
static class EntityTypeServiceImplTestContextConfiguration {
@Bean
public IEntityTypeService entityTypeService() {
return new EntityTypeServiceImpl();
}
}
@Autowired
private IEntityTypeService entityTypeService;
@MockBean
private EntityTypeRepository entityTypeRepository;
@Test
public void whenDelete_thenObjectShouldBeDeleted() {
final EntityType entity = new EntityType(1L, "new OET");
Mockito.when(entityTypeRepository.findById(1L).get()).thenReturn(entity).thenReturn(null);
// when
entityTypeService.delete(entity.getID());
// then
Mockito.verify(entityTypeRepository, times(1)).delete(entity);
assertThat(entityTypeRepository.findById(1L).get()).isNull();
}
}
当我运行测试时,我收到一条错误消息“java.util.NoSuchElementException: No value present”
java.util.NoSuchElementException: No value present
at java.util.Optional.get(Optional.java:135)
at xyz.unittests.service.EntityTypeServiceTest.whenDelete_thenObjectShouldBeDeleted(OriginatingEntityTypeServiceTest.java:41)
它引用了测试中的行Mockito.when(originatingEntityTypeRepository.findById(1L).get()).thenReturn(entity).thenReturn(null);
我认为我必须模拟该调用的原因是因为 Service 中的 delete 方法调用同一服务中的 getById() 方法,该方法又调用 entityTypeRepository.findById(id).get()
就是这样,我假设我必须模拟删除。但很明显我错了。任何援助将不胜感激。
非常感谢
解决方案
@Test
public void whenDelete_thenObjectShouldBeDeleted() {
final EntityType entity = new EntityType(1L, "new OET");
Optional<EntityType> optionalEntityType = Optional.of(entity);
Mockito.when(entityTypeRepository.findById(1L)).thenReturn(optionalEntityType);
// when
entityTypeService.delete(entity.getID());
// then
Mockito.verify(entityTypeRepository, times(1)).delete(entity);
//I dont think you need to assert to confirm actual delete as you are testing mock registry. to assert somethink like below you need to return null by mocking the same call again and return the null but thats of no use
//assertThat(entityTypeRepository.findById(1L).get()).isNull();
}
更新了你的测试。基本上我们首先需要模拟 findById 的结果。请参阅我上面的评论,断言实际删除。
推荐阅读
- android - ANDROID:如何使用轮廓框作为线性布局的背景?
- r - 在 R/shiny 中使用 renderTmap 时的反应性问题
- linux - 引用其他 shell 文件的 shell 文件以及调用它们的最佳方式
- serenity-bdd - Serenity 如何在测试 chrome 模拟器上运行(chrome web 浏览器中的移动模式)
- jquery - 拼接数组没有删除正确的位置并重叠同一个(jQuery)
- jquery - 尝试获取工作结果在 Postman 中完美运行,但在浏览器中使用 AJAX 需要 app_code 和 app_id
- html - 在 div HTML 中定位一些文本
- sql - 从 sysdate 获取上个月并将其存储为数字
- typescript - 在打字稿中获取数字文字类型值
- https - 通过 istio 网关公开 kibana(eck 运算符) - https 问题(错误 503)