我正在尝试模拟在另一个方法中调用的方法的行为,以便它模拟对象的返回,而在另一次方法引发异常时,则不进行模拟,但是否准确以及是否可能可能。
@Service
@Transactional
public class CategoryService {
@Autowired
private CategoryRepository repository;
public Category findById(Integer id) {
Optional<Category> obj = repository.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(id.toString()));
}
public Category update(Category category){
// Throws ObjectNotFoundException if not found before update
this.findById(category.getId());
return repository.save(category);
}
}
@RunWith(MockitoJUnitRunner.class)
public class CategoryServiceUnitTest {
@Mock
private CategoryService service;
@Test()
public void Should_UpdateCategory_When_FindCategory() {
Category cat = new Category(1, "Test");
//Is it possible?
when(service.findById(Mockito.anyInt())).thenReturn(cat);
Category category = service.update(cat);
assertThat(category.getName()).isEqualTo(cat.getName());
verify(service, times(1)).update(cat);
}
@Test(expected = ObjectNotFoundException.class)
public void Should_ThrowsObjectNotFoundException_When_NotFoudCategoryById() {
Category cat = new Category(1, "Test");
//Is it possible?
when(service.findById(Mockito.anyInt())).thenThrow(ObjectNotFoundException.class);
service.update(cat);
}
}
答案 0 :(得分:0)
正如评论中指出的那样,您想要做的是在测试中模拟CategoryRepository
。
@RunWith(MockitoJUnitRunner.class)
public class CategoryServiceTest {
private CategoryService service;
@Mock
private CategoryRepository repository;
@Before
public void setup() {
service = spy(new CategoryService(repository));
}
@Test
public void Should_UpdateCategory_When_FindCategory() throws ObjectNotFoundException {
Category cat = new Category(1, "Test");
when(repository.findById(Mockito.anyLong())).thenReturn(Optional.of(cat));
//return the category object that is used to call the repository.save(...) method
when(repository.save(Mockito.any(Category.class)))
.thenAnswer((Answer<Category>) invocation -> {
Object[] args = invocation.getArguments();
return (Category) args[0];
}
);
//depending on your requirements the above might be overkill, just replace that logic with this
//when(repository.save(Mockito.any(Category.class))).thenReturn(cat);
Category category = service.update(cat);
assertThat(category).isNotNull();
assertThat(category.getName()).isEqualTo(cat.getName());
verify(service).update(cat);
}
@Test(expected = ObjectNotFoundException.class)
public void Should_ThrowsObjectNotFoundException_When_NotFoudCategoryById() throws ObjectNotFoundException {
Category cat = new Category(1, "Test");
when(service.findById(Mockito.anyLong())).thenThrow(ObjectNotFoundException.class);
service.update(cat);
}
}
您还需要处理已检查的异常ObjectNotFoundException
。我刚刚将异常添加到方法签名中,您可能希望在生产设置中以不同的方式处理它
@Service
@Transactional
public class CategoryService {
private final CategoryRepository repository;
@Autowired
public CategoryService(CategoryRepository repository) {
this.repository = repository;
}
public Category findById(Long id) throws ObjectNotFoundException {
Optional<Category> obj = repository.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(id.toString()));
}
public Category update(Category category) throws ObjectNotFoundException {
// Throws ObjectNotFoundException if not found before update
this.findById(category.getId());
return repository.save(category);
}
}