• Java非Spring框架下的单元测试


    当下的大部分的Java项目都是基于Spring框架的,这固然带来了很大的便利,但是也引入了一些其他的问题。例如在对Service、Component进行单元测试的时候,虽然Junit等测试框架提供了相关框架的支持,但是如果是一个有点儿历史的、封装并不是很很合理的、方法类的单一职责做的不好的项目,进行一次单元测试,框架启动耗时30秒,测试方法5ms。时间举例有些极端,但这也是目前很多项目真实面临的情况。

    如何脱离框架支持,直接进行单元测试

    脱离框架的支持,直接进行单元测试,面临的第一个较大的问题就是“依赖”如何解决。Spring及Spring-boot框架解决的一个大问题就是依赖管理的问题,其提供的依赖注入和自动装配确实提供了很大的便利性,但在单元测试进行时最大的阻力就是这些依赖如何注入的问题。有框架支持的情况下可以从bean容器中拿来即用,但若是脱离了框架就需要手动进行初始化。

    如何解决

    测试需求介绍
    1. 本次需要对ClassA的aMethod方法进行单元测试,这是一个有一个入参:TestParam,和一个返回值:Result的方法。
    2. 在ClassA的Amethod方法中,分别调用了ClassB的bMethod方法和ClassC的cMethod方法。
    实现关键内容简介说明
    1. 被测试对象ClassA直接new出来一个真实的对象,里面的各种以来肯定是没有注入的。
    2. 对与被依赖的对象ClassB和ClassC,使用Mockito.mock(Class clazz)方法构建模拟对象出来。
    3. 使用反射将模拟对象clazzB和clazzC手动注入到被测试对象clazzA中。
    4. 使用Mockito的各种方法,对clazzB和clazzC进行加强。
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.mockito.runners.MockitoJUnitRunner;
    
    import java.lang.reflect.Field;
    
    // 指定运行器纯属个人习惯,使用默认的也可
    @RunWith(MockitoJUnitRunner.class)
    public class ClassATest {
    
        private final ClassA clazzA = new ClassA();
        private final ClassB clazzB = Mockito.mock(ClassB.class);
        private final ClassC clazzC = Mockito.mock(ClassC.class);
    
        @Test
        public void onceTest() throws IllegalAccessException {
            // 将需要的对象注入被测试对象
            Field[] declaredFields = ClassA.class.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                if (field.getName().equals("classA")) {
                    field.set(tradeOrderStore, orderNoUtil);
                } else if (field.getName().equals("clazzB")) {
                    field.set(tradeOrderStore, tradeProductUtil);
                }
            }
            //打桩、模拟
            Mockito.when(clazzB.bMethod(Mockito.any())).thenReturn("MC" + new Random().nextInt(1999999999));
            Mockito.when(clazzC.bMethod(Mockito.anyInt())).thenReturn(Boolean.TRUE);
            // 构建测试方法的入参
            TestParam tp = new TestParam();
            // 为测试入参设置测试值的代码省略......
            // 使用测试入参,执行测试方法
            Result testResult = clazzA.aMethod(tp);
            Assert.assertNotNull(testResult);
            // 其他测试验证省略......
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    通过以上,就可以脱离框架执行进行单元测试了,此时单元测试的运行执行就大大降低了。

  • 相关阅读:
    跨平台应用开发进阶(二十三) :一文走近 testflight 上架
    顶顶通语音识别使用说明
    56、springboot ------ RESTful服务及RESTful接口设计
    springboot+vue+elementui教师下乡支教岗位申请系统java项目源码
    Swing程序设计详解(一)
    python基本类型
    html旅游网站设计与实现——绿色古典旅游景区 HTML+CSS+JavaScript
    看看咱是如何用MATLAB白嫖遥遥领先于同行的神仙级翻译工具 — DeepL
    Redis的主从复制,哨兵和Cluster集群
    【斯坦福计网CS144项目】Lab3: TCPSender
  • 原文地址:https://blog.csdn.net/u011924665/article/details/126901147