SpringBoot利用ApplicationRunner 接口自定义单元测试

tech2026-04-19  2

  在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为CommandLineRunner和ApplicationRunner。他们的执行时机为容器启动完成的时候。

这两个接口中有一个run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。目前我在项目中用的是ApplicationRunner。是这么实现的:

先自定义注解 package com..dm.driver.dao.test;

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

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TestClass { }

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

package com..dm.driver.dao.test;

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.context.support.ApplicationObjectSupport; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method; import java.util.Map;

@Component public class DriverTest extends ApplicationObjectSupport implements ApplicationRunner {     private Logger logger = LoggerFactory.getLogger(getClass());

    int testCount;     int succCount;     @Override     public void run(ApplicationArguments args) throws Exception {         if(args.containsOption("test")) {  //启动时添加test为参数,待服务启动完成之后开始调用             logger.info("执行测试");             doTest(args);             System.exit(0);         }     }

    private void doTest(ApplicationArguments args) {         testCount = 0;         succCount = 0;         //扫描所有带有TestClass的注解类         Map<String ,Object> beans = getApplicationContext().getBeansWithAnnotation(TestClass.class);         for(Object  bean : beans.values()) {             logger.info("测试类{}", bean.getClass().getName());             ReflectionUtils.doWithMethods(bean.getClass(), m->testMethod(bean, m), m->m.isAnnotationPresent(TestMethod.class));         }         logger.info("testcount={} succcount={}", testCount, succCount);     }

    private void testMethod( Object bean, Method m) {         try {             logger.info("测试方法{}", m.getName());             testCount++;             Object ret = ReflectionUtils.invokeMethod(m, bean);             if(ret == null || ret instanceof Boolean && ((Boolean)ret)) {                 succCount++;             }         }catch(Throwable t) {             logger.error("测试失败", t);         }     } }

@Component @Lazy @TestClass //定义测试类 public class ClieckTest extends AbstractTest{     @Autowired     DmDriverService driverService;    @TestMethod  //定义测试方法     public boolean testPay1() {         RequestParameter parameter = new RequestParameter();         List<Response> response =  driverService.getResult(request);         System.out.println(JSON.toJSONString(response));         return response != null && response.size() > 0;

    }

    @TestMethod  //定义测试方法     public boolean testPlay2() {         RequestParameter parameter = new RequestParameter();         parameter.setAppversion("5.4.0");         List<Response> response =  driverService.getResult(request);         System.out.println(JSON.toJSONString(response));         response =  driverService.getNativeResult(nativeRequest);         System.out.println(JSON.toJSONString(response));         return response != null && response.size() > 0;     } }

最新回复(0)