Christian Bongiorno
Christian Bongiorno

Reputation: 5648

Spring AOP with custom annotation not working

I have looked at every example on stack exchange and on spring's example website and everything seems like this should work. I must be missing something simple

I have a custom annotation that ideally I would like to apply on either all methods of a class if the class is annotated or on any method annotated. Here is the aspect, test, and code:

Annotation

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD})
@Retention(RUNTIME)
public @interface Monitor {
    String value() default "Monitor";
}

Aspect

@Aspect
@Component
public class LatencyAspect {

    @Autowired
    private Logger logger;

    @Around("@annotation(Monitor)")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object retVal = joinPoint.proceed();

        logger.info("logged");

        return retVal;
    }
}

Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,classes = {LatencyConfig.class, LatencyTest.ContextConfiguration.class})
@ComponentScan
public class LatencyTest {
    final static Logger log = mock(Logger.class);

    @Autowired
    private SomeClass someClass;


    @Test
    public void testExample() throws Exception {
        someClass.doSomething("foo");
        verify(log).info("logged");

    }

    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @Configuration
    static class ContextConfiguration {


        @Bean
        public SomeClass properties() {
            return new SomeClass();
        }

        @Bean
        public Logger log() {
            return log;
        }
    }


    public static class SomeClass {

        @Monitor
        @Transient
        public String doSomething(String whatever) {
            return "done";
        }
    }
}

Result

Wanted but not invoked:
logger.info("logged");
-> at org.bongiorno.latency.LatencyTest.testExample(LatencyTest.java:74)
Actually, there were zero interactions with this mock.

Links

Actual source

Upvotes: 0

Views: 3321

Answers (1)

Nándor Előd Fekete
Nándor Előd Fekete

Reputation: 7098

Spring doesn't pick up the @ComponentScan annotation from a JUnit test class. Move the annotation to your LatencyConfig class or the test-local LatencyTest.ContextConfiguration inner configuration class.

Upvotes: 1

Related Questions