Jmokit

作者: 紫紫倩 | 来源:发表于2019-05-27 21:00 被阅读0次

    # Junit+Jmokit单元测试

    标签(空格分隔):java单元测试

    ---

    >  原理:mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。

    - 实质是一种替身的概念,代码基本上完全面向对象 JMockit的API易用,丰富! 写出来的Mock程序代码完全面向对象

    #第一阶段 环境准备

    1.开发环境已正确配置

    idea工具  maven  jdk

    2.工程解决JUnit依赖关系(pom.xml)

    junit依赖包

    jmockit依赖包

    Junit Generator架包 用于代码生成器的类

    pom.xml 依赖版本

            <dependency>

                <groupId>junit</groupId>

                <artifactId>junit</artifactId>

                <version>4.9</version>

            </dependency>

            <dependency>

                <groupId>org.jmockit</groupId>

                <artifactId>jmockit</artifactId>

                <version>1.15</version>

            </dependency>

    1.打开Settings窗口搜索Junit Generator,如图(两个插件都勾选添加):

    ![搜索juni插件.jpg-66.5kB][1]

    2.JUnitGenerator V2.0插件,可以帮助我们自动生成测试代码。如果搜索junit没有JUnitGenerator V2.0时,如下图操作(下载添加):

     ![下载插件或者导入插件.jpg-137.7kB][2]

     3.JUnitGenerator V2.0插件 配置

     ![日期乱码.jpg-142kB][3]

     4.JUnitGenerator V2.0代码生成操作如下:

      生成路径是当前类路径前面加一个test (test.com.bestpay.algorithm.impl)

    ![生成测试类的.png-88.2kB][4]

    #第二阶段 逻辑

    ###JMockit有两种测试方式,一种是基于行为的,一种是基于状态的测试。

        Behavior-oriented(Expectations & Verifications :

        通俗点讲,Behavior-oriented是基于行为的mock,对mock目标代码的行为进行模仿,更像黑盒测试

        State-oriented(MockUp<GenericType>) :

        是基于状态的mock,是站在目标测试代码内部的。可以对传入的参数进行检查、匹配,才返回某些结果,类似白盒

        而State-oriented的 new MockUp基本上可以mock任何代码或逻辑,MockUp用于静态方法打桩比较多。

    jmockit基本有三个步骤:

    (1)打桩。指定要打桩类和函数,模拟返回结果。Expectations()

    (2)调用被测方法。被测逻辑执行过程中,之前的打桩数据生效。

    (3)判断测试结果是否符合预期。Verifications()

    #第三阶段 实操

    1.@RunWith(JMockit.class)都被用作运行测试套件 增加运行注解,在这个才可以mocked,一般用于类之上

    #####在声明模拟字段和参数时,我们可以使用三种不同的模拟注释

    - @Mocked:Mocked修饰的类/接口,是让Jmockit生成一个Mocked对象,这个对象的方法(包含静态方法)返回默认值,如果返回类型是其他引用类型,则返回这个引用类型的Mocked对象.

    - @Tested:表示修饰的类,表示测试对象.

    - @Injectable:也表示Mocked一个对象,相比Mocked,只不过影响类的一个类的实例.

    - Expectations :主要用于录制类/对象的调用,返回值是什么.

    - @Mock直接Mock对象方法

    - 用Expectation来Mock类于Expectation来Mock实例唯一的不同在于,前者影响类的所有实例,后者只影响某一个类的实例

    CountDemo.class

        public class Count extends BaseRedisAggregation {

            public Count() {

                name = "Count";

            }

            @Override

            public Object process(SourceData data) {

                Map fields = paramsParser(data);

                    Jedis redis = redisSource.getRedis();

                    final String key = fields.get("key").toString();

                    final Integer target = 1;

                    final String maxStr = redis.hget(key, name);

                    if (StringUtils.isNotBlank(maxStr)) {

                        redis.hincrBy(key, name, 1);

                        if (redisSource.expireTime != -1) {

                        redis.expire(key, aggRange * redisSource.expireTime);

                    }

                }

                computeAggregation(fields.get("dimsKey").toString(), fields.get("timeKey").toString(),

                        fields.get("singleKey").toString(), aggRange, aggDimention, redis);

                redis.close();

                return null;

            }

            @Override

            public Map<String, Object> paramsParser(SourceData data) {

                String dimsKey = keyPreffix + data.get("dKey");

                String tKey = data.get("tKey");

                String timeKey = "";

                if (StringUtils.isNotBlank(tKey)) {

                    timeKey = TimeTransformater.getTimeStr(tKey, aggDimention);

                }

                String singleKey = "Single" + dimsKey;

                String key = singleKey + timeKey;

                String finalTimeKey = timeKey;

                Map<String, Object> algorithmnFileds = new HashMap<String, Object>() {{

                    put("dimsKey", dimsKey);

                    put("timeKey", finalTimeKey);

                    put("key", singleKey + finalTimeKey);

                    put("target", data.get("target"));

                    put("singleKey", singleKey);

                }};

                return algorithmnFileds;

            }

            public void computeAggregation(String dimKey, String timeStr, String singleKey, int range, char dimensionType, Jedis redis) {

                {

                    int totalCount = 0;

                    for (int i = 0; i < range; i++) {

                        String timeKey = "";

                        if (dimensionType != '0') {

                            timeKey = TimeTransformater.getLastIntervalTimeStr(dimensionType, timeStr, i);

                        }

                        String currRes = redis.hget(singleKey + timeKey,name);

                        if (StringUtils.isNoneBlank(currRes)) {

                            totalCount += Integer.valueOf(currRes);

                        }

                    }

                    redis.hset(dimKey, name, String.valueOf(totalCount));

                    redis.expire(dimKey, 24 * 60 * 60);

                }

            }

        }

    ####测试类 CountTestDemo.class

        /**

        * Count Tester.

        * @author <Authors name>

        * @since <pre>01/30, 2019</pre>

        * @version 1.0

        */

        @RunWith(JMockit.class)

        public class CountTest {

            @Tested

            Count count;

            @Mocked

            SourceData sourceDatas;

            @Mocked

            TimeTransformater timeTransformaters;

            @Mocked

            Jedis jedis;

            @Before

        public void before() throws Exception {}

        @After

        public void after() throws Exception {}

        /**

        * Method: process(SourceData data)

        */

        @Test

        public void testComputeAggregation() throws Exception {

            //打桩

            new Expectations(){

                {

              timeTransformaters.getLastIntervalTimeStr(anyChar,anyString,anyInt);      result = 1L;

                }

                {

                    jedis.hget(anyString, anyString); result = "100";

                }

                {

                    jedis.hset(anyString, anyString, anyString);result = 1l;

                }

                {

                    jedis.expire(anyString, anyInt); result =100l;

                }

            };

            count.computeAggregation("1","1","1",1,'a',jedis);

        //判断测试结果

          new Verifications() {

              {

                  jedis.hset("1","Count","100");times=1;

              }

          };

        }

        }

    > ####常见坑:

    >  1.@Tested /@Mocked 时保持格式一致统一对齐

    >  2.junit/jmockit依赖架包尽量不要存在多个版本

    >  3.测试中方法中,有用到继承属性值,在打桩后直接调用当前类的属性赋予值

    1.@Tested /@Mocked 时保持格式一致统一对齐

    ![格式2.png-48.9kB][5]

    3.测试中方法中,有用到继承属性值,在打桩后直接调用当前类的属性赋予值。

    ![例子.png-46.9kB][6]

      [1]: http://static.zybuluo.com/ziyi/afgogf3c5cu9sd99ft9x0kv4/%E6%90%9C%E7%B4%A2juni%E6%8F%92%E4%BB%B6.jpg

      [2]: http://static.zybuluo.com/ziyi/ag7rxeh0ycgacgh91t297hmj/%E4%B8%8B%E8%BD%BD%E6%8F%92%E4%BB%B6%E6%88%96%E8%80%85%E5%AF%BC%E5%85%A5%E6%8F%92%E4%BB%B6.jpg

      [3]: http://static.zybuluo.com/ziyi/bkzylyo385je9utf9xcsata4/%E6%97%A5%E6%9C%9F%E4%B9%B1%E7%A0%81.jpg

      [4]: http://static.zybuluo.com/ziyi/drtqcs12qmb35jbs4v70g8lb/%E7%94%9F%E6%88%90%E6%B5%8B%E8%AF%95%E7%B1%BB%E7%9A%84.png

      [5]: http://static.zybuluo.com/ziyi/jsc88jokl9dqvqc5glbg90dd/%E6%A0%BC%E5%BC%8F2.png

      [6]: http://static.zybuluo.com/ziyi/5n5vjbscn063g43gk04p56r4/%E4%BE%8B%E5%AD%90.png

    相关文章

      网友评论

          本文标题:Jmokit

          本文链接:https://www.haomeiwen.com/subject/cgbktctx.html