• 使用Spock 单元测试


    一、什么是Spock

    Spock 是一个测试框架,甚至可以说是一门语言他是基于Groovy开发的。它的语法完全遵循 BDD(行为驱动开发) 风格的结构。它是基于 Junit test runner 上开发但是又跟 Junit 完成不一样,同时集成了像 Jmock、Mockito 等语法表达风格于一体,使得它很简洁有很高的可读性。

     

    二、Spock 优缺点

    •   语法清晰简单并且有很高的可读性

    •   不好的就是需要学习下Groovy 的语法,对Maven的配置不是很友好。但是在Gradle 中可以很好的支持

      

    三、如何使用Spock

    Maven 的配置

     

    •   Gmavenplus-plugin 插件可以让你的测试代码支持 Groovy 语法
    •   Surefire 插件 测试时只执行带有 Spec后缀的代码,这个必须是*Spec.java 而不是 groovy
    •   spock-core 就是 spock 的核心包
    •   byte-buddy 用来做动态代理,如果你需要测试的代码没有实现接口。spock 无法帮你mock,当然你也可以用 cliglib 代替

    声明类

    /**
     *
     * @author: serio.shi(苦参)
     * @create 2020/08/05 17:22
     * */
    public class User {
    
        private int id;
        private String name;
        private int age;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    View Code

    Dao 类

    interface UserDao {
        public User get(int id);
        public User findByName(String name);
        public void createUser(User user);
    }
    View Code

    UserService 类

    /**
     *
     * @author: serio.shi(苦参)
     * @create 2020/08/05 17:23
     * */
    public class UserService {
    
        private UserDao userDao;
    
        public UserService(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public User findUser(int id){
            return userDao.get(id);
        }
    
        public void createUser(User user){
            User existing = userDao.findByName(user.getName());
    
            if(existing == null){
                userDao.createUser(user);
            } else{
                throw new RuntimeException(String.format("User with name %s already exists!", user.getName()));
            }
        }
    }
    View Code

    测试 service的findUser 方法 mock dao的get 方法返回一个固定 user

    是的你没有看错,它的方法名就是一个字符串(它有什么好处后面再讲)。它的语法很简单 given:、when:、then:、

    setup 是它的元方法在测试用例执行前调用类似于 @before

    •  given 需要的一些变量参数
    •  when 就是需要测试的方法
    •  then 就是期待的结果

    1 * dao.get(id) >> new User(id:id, name:"James", age:27)

    表示 dao.get(id) 方法将会被调用一次,并且让他返回 new User(id:id, name:"James", age:27) 对象。并且期待它的结果是 result.id == 1、result.name == "James"、result.age == 27

    在运行测试后

     

    从图中我们可以看到,我们定义的方法名被打印出来。我们可以很方便的看到我们想要测试的内容成功了。

    如果验证没有通过 Spock 将通过图表的方式告诉你哪里出问题,并且它会帮你把两个值的打印出来帮你做对比(经常有小伙伴写测试用例的时候把值打印出来用肉眼来识别错误)。我们把期待的id改为12再来试下。

     

     

      我们可以看到 Spock 提示你测试用例失败了,你的id 是1而期待的是12,当你点击 <Click to see difference> 的时候将会弹出一个框帮你做数据对比。简直是开发神器啊有木有!!!

    Spock 还有一个神奇的参数化测试,类似于表格的形式填入参数和期待的结果

    我们先在UserService类中加上以下代码:

    Map datatable = [1:"jerry", 2:"tom", 3:"tommy", 4:"jack"]
    public String getUser(int id){
        return datatable.get(id)
    }
    View Code

    添加测试用例:

    def "spock parameterized test demo"(){
        expect:
        service.getUser(id) == name
    where: "some id with name"
        id || name
        1  || "jerry"
        2  || "tom"
        3  || "tommy"
        4  || "jack"
    }

    可以看到我们可以以更清晰的方式把入参跟结果描述出来,运行结果:

     

    当前它还有很多的姿势待我们去解锁,本文只举例了简单的案例。

    更多详情点击:http://spockframework.org/spock/docs/1.3/all_in_one.html#_introduction

    四、小结

    Spock 有着依赖少、运行快、语法简单、代码清晰等特点、本文只做简单的举例用于学习和记录

  • 相关阅读:
    排序算法之——冒泡排序优化
    Linux程序在预处理、编译、汇编、链接、运行步骤的作用
    理解可变参数的原理
    对虚函数、虚表的认识
    成员函数的重载、覆盖、隐藏
    centOS7-mariadb的安装
    centOS7-本地源配置
    vmware中桥接、NET、仅主机模式详解
    XXX系统项目目标文档课堂讨论
    做生活的有心人——xxx系统第一阶段总结
  • 原文地址:https://www.cnblogs.com/lionsblog/p/13446640.html
Copyright © 2020-2023  润新知