java - 如何用SpringBootTest测试一个方面?

标签 java spring-boot aop aspectj

我使用 Spring Boot 2.1.6.RELEASE 在 Spring 中创建了一个简单的方面。 它基本上记录了花费在一种方法上的总时间。

@Aspect
@Component
public class TimeLoggerAspect {

  private static final Logger log = LoggerFactory.getLogger(TimeLoggerAspect.class);

  @Around("@annotation(demo.TimeLogger)")
  public Object methodTimeLogger(ProceedingJoinPoint joinPoint) 
          throws Throwable {
    long startTime = System.currentTimeMillis();

    Object proceed = joinPoint.proceed();

    long totalTime = System.currentTimeMillis() - startTime;
    log.info("Method " + joinPoint.getSignature() + ": " + totalTime + "ms");

    return proceed;
  }
}

方面由TimeLogger注解触发

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimeLogger {
}

并在这样的组件中使用

@Component
public class DemoComponent {
  @TimeLogger
  public void sayHello() {
    System.out.println("hello");
  }
}

spring boot 演示应用程序将通过CommandLineRunner 接口(interface)的run 方法调用sayHello

@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

  @Autowired
  private DemoComponent demoComponent;

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    demoComponent.sayHello();
  }
}

为了完整性,我在 build.gradle 中添加了我的修改:为 aop、spring test 和 jupiter (junit) 添加库。

    compile("org.springframework.boot:spring-boot-starter-aop")

    testCompile("org.springframework.boot:spring-boot-starter-test")
    testCompile("org.junit.jupiter:junit-jupiter-api")
    testRuntime("org.junit.jupiter:junit-jupiter-engine")

运行应用程序将输出(为便于阅读而修剪)

hello
... TimeLoggerAspect : Method void demo.DemoComponent.sayHello(): 4ms

到目前为止,还不错。现在,我基于 @SpringBootTest 注释和 jupiter 创建了一个测试。

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {DemoComponent.class, TimeLoggerAspect.class})
public class DemoComponentFailTest {

  @Autowired
  private DemoComponent demoComponent;

  @Test
  public void shouldLogMethodTiming() {
      demoComponent.sayHello();
  }
}

这里我得到了输出

hello

TimeLoggerAspect 没有输出,因为它似乎没有被触发。

是否缺少触发测试方面的内容?还是有其他方法可以在 spring boot 中测试方面?

最佳答案

我遇到了类似的问题。我的方面正在监听 Controller 方法。要激活它,导入 AnnotationAwareAspectJAutoProxyCreator 就可以了:

@RunWith(SpringRunner.class)
@Import(AnnotationAwareAspectJAutoProxyCreator.class) // activate aspect
@WebMvcTest(MyController.class)
public class MyControllerTest {

    ...

}

关于java - 如何用SpringBootTest测试一个方面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56763066/

相关文章:

java - 对于尝试访问不可读文件的 JAVA 程序,unix 看到的用户名是什么

java - java中将一个链表添加到另一个链表

java - 如何为junit编写通用的tearDown方法?

java - 在EnvironmentPostProcessor中获取ServletContext

c# - winform 的 AOP

java - 为什么 JBoss 只创建一个 ActiveMQ 消费者?

初始化错误thread-10中的Java异常

java - 使用 Oracle 的 Spring Boot 应用程序 - ORA-01000 : maximum open cursors exceeded - error happening during load testing

Spring Aspects 不执行

c# - 记录-改变实现?