WantBecomeJavaCoder
WantBecomeJavaCoder

Reputation: 63

Spring AOP AfterThrowing aspect doesn't work with mock objects in Junit 5

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

Upvotes: 1

Views: 716

Answers (1)

R.G
R.G

Reputation: 7131

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();
            }
        };
    }
}

Upvotes: 2

Related Questions