使用 JUnit 测试带有 if/else 语句的 void 方法莫基托
使用Juinit 5和Mockito测试方法的正确方法是什么?我发现了两个测试用例,当Artmerk阵列大小为零时,并且当大于零时,但是在第二种情况下,我无法验证Artmerkrepository.save(tosave)和artmerkrepository.deleteinbatch(oldlist)这两个方法。
@Service
public class ItemService{
@Autowired
ArtMerkRepository artMerkRepository;
@Autowired
ItemServiceRestClient itemServiceRestClient;
public void updateOrInsertArtMerk(String artNr) {
LOGGER.info("Start saving ArtMerk.");
ArtMerk[] artMerk = itemServiceRestClient.getArtMerk(artNr);
if(artMerk != null) {
if(artMerk.length == 0) {
artMerkRepository.deleteByArtNr(artNr);
}else {
for (ArtMerk a : artMerk) {
List<ArtMerk> aExists = artMerkRepository.findByArtNr(a.getArtNr());
ArtMerk toSave = (aExists != null && !aExists.isEmpty()) ? UpdateUtils.updateArtMerk(aExists.get(0), a) : a;
artMerkRepository.save(toSave);
}
List<ArtMerk> newList = new ArrayList<>(Arrays.asList(artMerk.clone()));
List<ArtMerk> oldList = new ArrayList<>(artMerkRepository.findByArtNr(artNr));
oldList.removeAll(newList);
if (oldList != null && oldList.size() > 0) {
artMerkRepository.deleteInBatch(oldList);
}
}
}
LOGGER.info("Successful update of ArtMerk.");
}
}
我的测试方法看起来像这样:
@Test
void updateOrInsertArtMerk_whenArtMerkArrSizeIsNotZero() {
//given
String artNr = "0001";
ArtMerk artMerk1 = new ArtMerk();
artMerk1.setArtNr(artNr);
ArtMerk artMerk2 = new ArtMerk();
artMerk2.setArtNr(artNr);
List<ArtMerk> oldList = Arrays.asList(artMerk1, artMerk2);
ArtMerk[] artMerks = new ArtMerk[]{artMerk1};
//when
when(itemServiceRestClient.getArtMerk(artNr)).thenReturn(artMerks);
when(artMerkRepository.findByArtNr(artNr)).thenReturn(Arrays.asList(artMerks));
when(artMerkRepository.save(artMerk1)).thenReturn(artMerk1);
when(artMerkRepository.findByArtNr(artNr)).thenReturn(oldList);
doNothing().when(artMerkRepository).deleteInBatch(oldList);
//then
itemService.updateOrInsertArtMerk(artNr);
verify(artMerkRepository, times(2)).findByArtNr(artNr);
verify(artMerkRepository, times(1)).save(artMerk1);
verify(artMerkRepository, times(1)).deleteInBatch(oldList);
}
@Test
void updateOrInsertArtMerk_whenArtMerkArrSizeIsZero() {
//given
String artNr = "0001";
ArtMerk[] artMerks = new ArtMerk[]{};
//when
when(itemServiceRestClient.getArtMerk(artNr)).thenReturn(artMerks);
doNothing().when(artMerkRepository).deleteByArtNr(artNr);
//then
itemService.updateOrInsertArtMerk(artNr);
verify(artMerkRepository, times(1)).deleteByArtNr(artNr);
}
第一个测试方法由于不必要的刺激性而失败。
What is correct way to test method like this, using JUinit 5 and Mockito ? I found two test cases, when artMerk array size is zero, and when is greater than zero, but in second case, I couldn't verify that both method artMerkRepository.save(toSave) and artMerkRepository.deleteInBatch(oldList) are called.
@Service
public class ItemService{
@Autowired
ArtMerkRepository artMerkRepository;
@Autowired
ItemServiceRestClient itemServiceRestClient;
public void updateOrInsertArtMerk(String artNr) {
LOGGER.info("Start saving ArtMerk.");
ArtMerk[] artMerk = itemServiceRestClient.getArtMerk(artNr);
if(artMerk != null) {
if(artMerk.length == 0) {
artMerkRepository.deleteByArtNr(artNr);
}else {
for (ArtMerk a : artMerk) {
List<ArtMerk> aExists = artMerkRepository.findByArtNr(a.getArtNr());
ArtMerk toSave = (aExists != null && !aExists.isEmpty()) ? UpdateUtils.updateArtMerk(aExists.get(0), a) : a;
artMerkRepository.save(toSave);
}
List<ArtMerk> newList = new ArrayList<>(Arrays.asList(artMerk.clone()));
List<ArtMerk> oldList = new ArrayList<>(artMerkRepository.findByArtNr(artNr));
oldList.removeAll(newList);
if (oldList != null && oldList.size() > 0) {
artMerkRepository.deleteInBatch(oldList);
}
}
}
LOGGER.info("Successful update of ArtMerk.");
}
}
My test methods looks like this:
@Test
void updateOrInsertArtMerk_whenArtMerkArrSizeIsNotZero() {
//given
String artNr = "0001";
ArtMerk artMerk1 = new ArtMerk();
artMerk1.setArtNr(artNr);
ArtMerk artMerk2 = new ArtMerk();
artMerk2.setArtNr(artNr);
List<ArtMerk> oldList = Arrays.asList(artMerk1, artMerk2);
ArtMerk[] artMerks = new ArtMerk[]{artMerk1};
//when
when(itemServiceRestClient.getArtMerk(artNr)).thenReturn(artMerks);
when(artMerkRepository.findByArtNr(artNr)).thenReturn(Arrays.asList(artMerks));
when(artMerkRepository.save(artMerk1)).thenReturn(artMerk1);
when(artMerkRepository.findByArtNr(artNr)).thenReturn(oldList);
doNothing().when(artMerkRepository).deleteInBatch(oldList);
//then
itemService.updateOrInsertArtMerk(artNr);
verify(artMerkRepository, times(2)).findByArtNr(artNr);
verify(artMerkRepository, times(1)).save(artMerk1);
verify(artMerkRepository, times(1)).deleteInBatch(oldList);
}
@Test
void updateOrInsertArtMerk_whenArtMerkArrSizeIsZero() {
//given
String artNr = "0001";
ArtMerk[] artMerks = new ArtMerk[]{};
//when
when(itemServiceRestClient.getArtMerk(artNr)).thenReturn(artMerks);
doNothing().when(artMerkRepository).deleteByArtNr(artNr);
//then
itemService.updateOrInsertArtMerk(artNr);
verify(artMerkRepository, times(1)).deleteByArtNr(artNr);
}
And first test method fails because of UnnecessaryStubbingException.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该通过构造函数注入它们,而不是
您的依赖性。
这样,您可以在测试期间注入
模拟
对象,而不是使用类似Instead of
your dependencies, you should inject them via a constructor.
This way, you can inject during test a
mock
object and than use something like