Spring AOP с макетом, Spy. AspectJProxyFactory не может добавить макет экземпляра addAspect

#unit-testing #junit #mockito #spring-aop

#модульное тестирование #junit #mockito #spring-aop

Вопрос:

Я пробую модульные тесты, в которых класс аспектов хорошо работает во время модульного тестирования.

Изменение ситуации.

  • обновите Spring Boot с 1.5.9 -> 2.3.1.
  • Фреймворки Mockito, Junit увеличены (mockito-core 1.10.19 -> 3.3.3)

У меня проблема в том, что модульные тесты для Spring AOP (внутренне AspectJ) не будут проходить при обновлении. Причина в том, откуда AbstractAspectJAdvisorFactory class проверяет, является ли данный класс аспектов реальным классом аспектов или нет.

Мой код

     @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 amp;amp;
            !Modifier.isAbstract(aspectClass.getSuperclass().getModifiers())) {
        throw new AopConfigException("["   aspectClass.getName()   "] cannot extend concrete aspect ["  
                    aspectClass.getSuperclass().getName()   "]");
    }
...
  

Все работало как обычно. Однако после обновления с mockito-core 1.10.19 до 3.3.3 я обнаружил, что проверка завершилась неудачно из-за другого макетного класса.

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

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

Мое исследование приведено ниже. Я только что обнаружил, что Spring AOP использует не Mockito в качестве внедренного аспекта, а реальный экземпляр и его переменные. Я не мог найти правильный способ ожидать код. Как я могу попробовать с 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. Вы решили это?

2. @MariaInesParnisari Нет. Сейчас я просто временно пропускаю модульный тест.

Ответ №1:

Замена

 aspectJProxyFactory.addAspect(aspect);
  

с

 aspectJProxyFactory.addAspect(RepositoryAspect.class);
  

Устраняет эту проблему, и аспект запускается (хотя это не помогает разрешить проверку самого аспекта в тесте, если это цель)