'Spring AOP with Mock, Spy. AspectJProxyFactory cannot addAspect Mock instance

I am trying unit tests where an aspect class works well while unit testing.

Situtation.

  • upgrade Spring Boot from 1.5.9 -> 2.3.1.
  • Mockito, Junit frameworks are bumped up (mockito-core 1.10.19 -> 3.3.3)

I have a problem that unit tests for Spring AOP (internally AspectJ) will not pass while upgrading. The cause is from where AbstractAspectJAdvisorFactory class validates whether a given aspect class is a real aspect class or not.

My code

    @Mock
    private RepositoryAspect aspect;

    @InjectMocks
    private NicknameRepository nicknameRepository;

    @Before
    public void setup() {

        AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(nicknameRepository);
        aspectJProxyFactory.addAspect(aspect); // fails 
        nicknameRepository = aspectJProxyFactory.getProxy();
    }

https://github.com/spring-projects/spring-framework/blob/0819a9fcc9a1168521995e0bac7de5633a819780/spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactory.java#L105-L110

public void validate(Class<?> aspectClass) throws AopConfigException {
    // If the parent has the annotation and isn't abstract it's an error
    if (aspectClass.getSuperclass().getAnnotation(Aspect.class) != null &&
            !Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
        throw new AopConfigException("[" + aspectClass.getName() + "] cannot extend concrete aspect [" +
                    aspectClass.getSuperclass().getName() + "]");
    }
...

It worked as normal. However, after upgrading from mockito-core 1.10.19 to 3.3.3, I found the validation fails due to different wrapped Mock class.

1.10.19
<instance>$$EnhancerByMockitoWithCGLIB => not classified as a Mock class

3.3.3
<instance>$$MockitoMock => classified wrapped Mock class, not an aspect class

My research is below. I just found Spring AOP does not use Mockito as an injected aspect, but a real instance and its variables. I couldn't find a right way expect the code. How can I try with Mockito?

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/aspectj/annotation/AspectJProxyFactory.html

http://useof.org/java-open-source/org.springframework.aop.aspectj.annotation.AspectJProxyFactory

https://github.com/spring-projects/spring-framework/blob/3aa2605fdaa56d5c007f476f3f9bd1c550ec368c/spring-context/src/test/java/org/springframework/aop/aspectj/BeanNamePointcutAtAspectTests.java



Solution 1:[1]

Replacing

aspectJProxyFactory.addAspect(aspect);

with

aspectJProxyFactory.addAspect(RepositoryAspect.class);

Gets past this problem and the aspect is triggered (though it doesn't help resolve verifying the aspect itself in test, if that's the goal)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tanel