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

Viewed 536

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

1 Answers

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)

Related