4年前 (2020-08-20)  Spock系列 |   2 条评论  2018 
文章评分 3 次,平均分 5.0

Spock虽然好用,但要应用到实际项目中还是需要注意几个问题,下面讲下我们公司在使用过程中遇到的一些问题和解决方案

版本依赖

要使用Spock首先需要引入相关依赖,目前使用下来和我们项目兼容的Spock版本是1.3-groovy-2.5,以maven为例(gradle可以参考官网),完整的pom依赖如下:

<spock.version>1.3-groovy-2.5</spock.version>
<groovy.version>2.5.4</groovy.version>
 
<!-- spock -->
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-core</artifactId>
    <version>${spock.version}</version>
    <scope>test</scope>
</dependency>
<!-- spock和spring集成 -->
<dependency>
    <groupId>org.spockframework</groupId>
    <artifactId>spock-spring</artifactId>
    <version>${spock.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>test</scope>
</dependency>
<!-- spock依赖的groovy -->
<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <type>pom</type>
    <version>${groovy.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>groovy-test-junit5</artifactId>
            <groupId>org.codehaus.groovy</groupId>
        </exclusion>
        <exclusion>
            <artifactId>groovy-testng</artifactId>
            <groupId>org.codehaus.groovy</groupId>
        </exclusion>
    </exclusions>
</dependency>
 
<!--groovy 编译-->
<plugin>
    <groupId>org.codehaus.gmavenplus</groupId>
    <artifactId>gmavenplus-plugin</artifactId>
    <version>1.6</version>
    <executions>
        <execution>
            <goals>
                <goal>compile</goal>
                <goal>compileTests</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Spock是使用groovy语言写单测的,所以需要引入groovy-all的依赖

在引入 groovy-all 包时排除了 groovy-test-junit5 和 groovy-testng,这两个包和和 power mock 有冲突,在执行 mvn test 会导致NPE的问题

如果你的项目中没有用过groovy,还需要添加groovy的maven编译插件,这样才能编译我们用Spock写的单元测试

引入groovy依赖后可能会出现版本冲突的问题,因为如果你的项目引用了springboot-start-base这样的集合式jar包,它里面也会引用groovy,有可能跟我们引入的groovy包版本出现冲突,或者公司的一些框架也会引用groovy的包,如果版本不一致也有可能冲突,需要排下包

然后执行 mvn clean compile 验证下是否有冲突,如果能成功编译就没有这个问题

目前Spock的最新版本是2.0以上,在Spock 2.x 的版本里官方团队已经移除Sputnik,不再支持代理运行power mock的方式

因为Spock 2.0是基于JUnit5,我们项目以前的单元测试代码都是基于Junit4编写的,换成Junit5后,需要修改现有的java单测,比如指定代理运行,使用power mock的地方要换成Junit5的扩展语法

对现有使用Junit4 + power mock/jmockit的方式改变较大,为降低迁移成本没有使用最新的Spock2.X版本

如果你的项目之前就是使用Junit5写单测的,那么可以使用Spock2.X的版本,2.0以上版本使用power mock可以参考官方提供的解决方案:

Spock注意事项

(http://github.com/spockframework/spock/commit/fa8bd57cbb2decd70647a5b5bc095ba3fdc88ee9)

后续我也会优先在我的博客(www.javakk.com)推出 Spock2.x 版本的使用教程

创建单元测试文件

编译(mvn clean compile)通过之后,用spock编写的groovy类型的单测代码不能放在原来的test/java目录下面

因为按照groovy的约定,默认编译groovy包下的单测,所以需要建个groovy文件夹存放spock的单测代码,如下图所示:

Spock注意事项

这样也方便区分原来Java单测和用Spock写的单测代码

另外记得别忘了标记groovy目录为测试源目录(Test Source Root),如下图:

Spock注意事项

(groovy文件夹右键 → Mark Directory as → Test Sources Root)

第一次运行spock单测代码时如果提示"no test suite exist"的错误,可以右键recompile下

还有记得创建的单测文件类型是Groovy Class,不是Java Class类型

Spock注意事项

最后使用intellij idea的快捷键创建单元测试,在需要测试的类或方法上右键IDE的菜单,选择"Go To → Create New Test" 选择我们已经创建好的groovy文件夹:

Spock注意事项

Spock注意事项

Spock注意事项

这样就自动生成了groovy类型的单测文件了

运行单元测试

执行 mvn test,按照上面两步的配置保证spock单测代码运行成功后可以执行 mvn clean test 命令,跑一下这个项目的单测用例

(这一步不是必须的,但如果公司加了单测覆盖率的统计时,在cicd系统发布时或merge request to release代码合并到release分支时,会先执行mvn test类似的指令,确保所有的单元测试运行成功)

如果你的项目和我们一样既有Java单测又有Spock单测,需要确保两种单测都能执行成功(目前我们项目的spock单测和java单测在公司的CICD系统以及git上都能兼容和通过测试覆盖率要求)

另外按照Spock的规范,单测代码文件的命名应该是以Spec为后缀的,如果你严格按照这个规范命名单测文件,比如"OrderServiceSpec.groovy",那么需要在maven-surefire-plugin测试插件里添加以Spec为后缀的配置:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <configuration>
        <includes>
            <include>**/*Spec.java</include>
            <include>**/*Test.java</include>
        </includes>
    </configuration>
</plugin>

但是我是直接使用IDE生成单元测试,intellij idea自动生成的单测后缀还是“Test”,所以不存在这个问题,如果你也是这样,可以忽略这个问题

单元测试规范

Spock虽然使用方便,但还是要遵循单元测试的规范来,比如单元测试一般是针对方法或类的维度去测试的,也就是说我们关注的重点是当前类或方法内部的逻辑

如果当前被测方法依赖了其他层或module的逻辑,最好mock掉,尽量不要跨层测试,这属于功能测试或集成测试的范畴

比如使用@SpringBootTest注解,默认会把当前方法依赖的下一层引用也注入进来,其实完全可以交给Spock去控制,可以不需要SpringBootTest

后续如果新的问题或注意事项会持续更新

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/322.html

关于

发表评论

表情 格式
  1. 老哥啥时候推出:Spock2.x 版本的使用教程,期待。。。

    Smart Shark 评论达人 LV.1 3年前 (2021-09-22) [0] [0]
    • @Smart SharkSpock2.X是基于Junit5,你们项目使用的是junit5吗?(junit5和4差异蛮大的,因为我们项目大部分都是junit4的,我了解下5的使用情况吧)

      sofia 博 主 3年前 (2021-09-25) [0] [0]

登录

忘记密码 ?

切换登录

注册