zoukankan      html  css  js  c++  java
  • 【maven】【spring boot】【单元测试】 使用controller 执行单元测试类

      存在这样一个场景: 

        当项目启动时间过长,又没办法缩短的时候,写单元测试就是一个十分耗时的工作,

        这工作不在于使用编写代码,而在于每次run junit test 都需要完整启动一次项目,白白浪费宝贵的生命。

        当由于某个字段没有赋值,或者某个简单判断写错,导致需要再等个3-5分钟启动 junit test,是否会想要执行一次san check?  

      于是乎:

        假若能使用controller来调用test类方法的话,那么在本地调试单元测试时,对于一些简单的代码修改,

        通过热部署,只需要重新进行一次url访问就可执行一个完整的单元测试,

        无需再次启动整个项目。

      正题:

        1. 如何在controller访问src/test ?

        2. 如何编写 ?

      如何在controller访问src/test

        maven项目的默认配置中, src/test目录是测试目录,不会被编译到jar中,也就是在controller调用时会报ClassNotFoundException

        解决办法最好的是在pom文件中修改maven默认的测试目录,将src/test 作为正常目录使用

        <build><!-- 将测试目录更改为其他目录 -->
        	<testSourceDirectory>src/main/test</testSourceDirectory> 
        </build>
    

      需要重新maven-update。update后重新将src/test use for building path

      完成后便可以成功启动项目,并可以正常访问。

      如何编写

        可以做一个参考:

    controller,最主要内容在于使用controller时,junit的自动回滚可能不会生效,所以手动设置事务,手动触发回滚

    @RestController
    @RequestMapping(value = "/junit", produces = "application/json;charset=utf-8")
    public class TestController {
        
        private final Logger logger = LoggerFactory.getLogger(TestController.class);
        
        @Autowired
        private BizTest bizTest;
    
        @GetMapping("test")
    @Transactional(rollbackFor = Exception.class)
    public void startJunit() { bizTest.insertTest(); // 手动开启事务回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }

    测试类,即可以通过其他类访问,也可以直接执行junit,增加@Componet 或者@Service 还可以通过spring注入方式调用

    @Component
    public class BizTest extends AbstractTest {
    
        @Autowired
        private Biz biz;
        
        @Test
        public void insertTest() {
            // 测试业务
        }
    }

    测试抽象父类,用于直接使用junit测试时的配置

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = WebApplication.class)
    @Transactional
    // @Rollback(false)
    public abstract class AbstractTest {
    
        protected final Logger logger = LoggerFactory.getLogger(AbstractTest.class);
    
        protected void println(Object object) {
            System.out.println(object);
        }
    }

    改进: Controller 与Test类解耦

      直接在controller引用Test类,提交代码后容易引起打包错误,这里就需要对两者进行解耦。

      咱的解决办法如下:

         利用spring动态bean注册+类限定名来令两者解耦,并令Test类接受spring容器管理,代码如下:

    @GetMapping("test")
        @ResponseBody
        public String startJunit() {
         // 测试主类限定名 String testImplName
    = "com.terra.test.JunitTester";
         // 若bean未注册,则注册,SpringConetxtUtil可参考其余地方的Spring动态注册bean
    if (SpringContextUtil.getBean(testImplName) == null) { registerBean(testImplName); } try { IJunitTest junitTester = SpringContextUtil.getBean(testImplName); junitTester.startTest(); } catch (Exception e) { if (e.getClass() != UnexpectedRollbackException.class) { return e.getMessage(); } } logger.info("执行单元测试成功"); return "操作成功, 执行完成时间:" + DateUtil.getNowDateTime(); }   // 注册bean private void registerBean(String className) { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) SpringContextUtil.getApplicationContext().getAutowireCapableBeanFactory(); if (beanFactory.getBean(className) == null) { BeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClassName(className); beanFactory.registerBeanDefinition(className, beanDefinition); } }   // 单元测试主类接口 public static interface IJunitTest { void startTest(); }

    测试主类代码:

    @Component
    public class JunitTester extends AbstractTest implements IJunitTest {
    
        @Autowired
        private BizTest1 bizTest1;
        @Autowired
        private BizTest2 bizTest2;
    
        @Transactional(rollbackFor = Exception.class)
        @Override
        public void startTest() {
            // 手动开启事务回滚
            bizTest1.before();
            bizTest1.test();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    这样做的好处是,环境上的代码没有src/test也不会报错,而本地只需要进行注释和去除注释@RequestMapping,便无需要再修改controller代码

    所有单元测试代码操作便可在测试主类及其测试类中进行,可喜可贺。

  • 相关阅读:
    查看索引执行次数
    解决TFS服务器重命名后,无法访问的问题
    C#匿名方法增加、删除委托
    Silverlight 4 正确设置 ScrollViewer让它更好的支持鼠标滚轮
    Win8 loading 动画 Silverlight版本
    Silverlight控件自适应利器UseLayoutRounding属性(解决自适应抖动问题)
    添加从Web下载的dll引用,VS提示错误
    IQueryable<T>获取查询计划(SQL)
    WinForm多线程+委托防止界面假死
    ASP.net(c#)生成条形码 code39条码生成方法
  • 原文地址:https://www.cnblogs.com/syui-terra/p/11321719.html
Copyright © 2011-2022 走看看