admin管理员组文章数量:1241125
I'm using spring-boot 3.4.2.
I want to use AOP aspects in order to modify annotations that I use in a spring boot test.
However my @Around method is not triggered during test execution. If I annotate e.g. an endpoint method inside a rest controller, than it is triggered. But I want to use it for tests.
Here's my annotation:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
Here's my Aspect:
@Aspect
@Component
public class TestAspect {
public TestAspect() {
// this is called - so @Component works
System.out.println("aspect constructor called");
}
@Around("@annotation(TestAnnotation)")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// this is NOT called in the test - @Around did not work
System.out.println("aroundAdvice() called");
return joinPoint.proceed();
}
}
And here's my test:
@SpringBootTest
@ComponentScan(basePackages = { "de.mycompany" }) // root of all my packages
@TestPropertySource(value = "classpath:application-test.yml", factory = YamlPropertySourceFactory.class)
@AutoConfigureMockMvc
class MyTestClass {
@Autowired
private MockMvc mockMvc;
@Test
@TestAnnotation
void testSomething() throws Exception {
System.out.println("testSomething() called.");
// test something with mockMvc
}
}
If I annotate an endpoint in a RestController, aroundAdvice()
will be triggered, whenever that endpoint is called or tested.
But I need it to be triggered when my test method (here: testSomething()
) is called. And that does not work.
Using the fully qualified class in @Around
doesn't work either:
@Around("@annotation(de.mycompany.annotation.TestAnnotation)")
I'm using spring-boot 3.4.2.
I want to use AOP aspects in order to modify annotations that I use in a spring boot test.
However my @Around method is not triggered during test execution. If I annotate e.g. an endpoint method inside a rest controller, than it is triggered. But I want to use it for tests.
Here's my annotation:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
Here's my Aspect:
@Aspect
@Component
public class TestAspect {
public TestAspect() {
// this is called - so @Component works
System.out.println("aspect constructor called");
}
@Around("@annotation(TestAnnotation)")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
// this is NOT called in the test - @Around did not work
System.out.println("aroundAdvice() called");
return joinPoint.proceed();
}
}
And here's my test:
@SpringBootTest
@ComponentScan(basePackages = { "de.mycompany" }) // root of all my packages
@TestPropertySource(value = "classpath:application-test.yml", factory = YamlPropertySourceFactory.class)
@AutoConfigureMockMvc
class MyTestClass {
@Autowired
private MockMvc mockMvc;
@Test
@TestAnnotation
void testSomething() throws Exception {
System.out.println("testSomething() called.");
// test something with mockMvc
}
}
If I annotate an endpoint in a RestController, aroundAdvice()
will be triggered, whenever that endpoint is called or tested.
But I need it to be triggered when my test method (here: testSomething()
) is called. And that does not work.
Using the fully qualified class in @Around
doesn't work either:
@Around("@annotation(de.mycompany.annotation.TestAnnotation)")
- AOP works for spring managed beans the test isn't spring managed. If you want that to work you will need to setup load- or compile timeweaving instead of using proxies (the default). – M. Deinum Commented 2 days ago
1 Answer
Reset to default 0Annotations only work on beans. They work by creating proxy. Your MyTestClass
is not real Spring bean.
One way to implement what you want is to implement extension and check for annotation in InvocationInterceptor
.
public class MyExtension implements InvocationInterceptor {
public void interceptTestMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
doMyStuff(invocationContext);
invocation.proceed();
}
public <T> T interceptTestFactoryMethod(Invocation<T> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
doMyStuff(invocationContext);
return invocation.proceed();
}
public void interceptTestTemplateMethod(Invocation<Void> invocation, ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext) throws Throwable {
doMyStuff(invocationContext);
invocation.proceed();
}
void doMyStuff(ReflectiveInvocationContext<Method> invocationContext) {
Method m = invocationContext.getExecutable();
TestAnnotation a = m.getAnnotation(TestAnnotation .class);
if(a != null){
System.out.println("Here we go");
}
}
}
Put that extension on your test by adding @ExtendWith(MyExtension.class)
to your test class.
本文标签: javaAOP Aspect not triggered in SpringBootTestStack Overflow
版权声明:本文标题:java - AOP @Aspect not triggered in @SpringBootTest - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740104334a2225012.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论