Issue
in my spring project I created simple aspect which catches DaoExceptions and turns them into service exceptions
@Aspect
@Component
public class ExceptionAspect {
@Pointcut("execution(public * *(..))")
private void allPublicMethods() {
}
@Pointcut("within(img.imaginary.dao.*)")
private void inDao() {
}
@AfterThrowing(pointcut = "allPublicMethods() && inDao()", throwing = "exception")
public void afterThrowing(JoinPoint joinPoint, DaoException exception) {
throw new ServiceException(String.format("%s in method %s %s class", exception.getMessage(),
joinPoint.getSignature().getName(), joinPoint.getTarget().getClass().getSimpleName()), exception);
}
}
and it works fine when DaoException throwing from dao layer to service it turns into Service exception
but only not in the tests:
@Test
void findById_ShouldThrowServiceException_WhenEntityNotFound() {
Mockito.when(defaultDao.findById(0)).thenThrow(DaoException.class);
assertThrows(ServiceException.class, () -> defaultServiceImpl.findById(0));
}
in this test I have a defaultDao and it is a Mock object and when it throws a DaoException my aspect does not catch and proxy it
I can't figure out how to solve this problem
Solution
With the following assumptions - it is a spring-boot project , defaultDao
is a mocked bean using @MockBean
Do go through the issue to understand why @MockBean
will not work.
Following code would mock a bean and throw an exception . You will need to adjust the code to make it work for you.( eg: @SpringBootTest
may or may not be required for your case ).
@SpringBootTest
class DefaultDaoTest {
@Autowired
DefaultDao defaultDao;
@Test
void test() {
assertThrows(ServiceException.class, () -> defaultDao.findById(0));
}
}
@Configuration
class TestConfig {
@Bean
@Primary
public DefaultDao defaultDao() {
return new DefaultDao() {
@Override
public Object findById(Long id) {
throw new DaoException();
}
};
}
}
Answered By - R.G
Answer Checked By - Mildred Charles (JavaFixing Admin)