1.spock介绍
Spock 框架是一个基于groovy语法的测试框架,由于使用groovy,所以使用起来比 junit 更加灵活,测试用例的写法更加简单易懂,一目了然
2.maven
<!-- h2database 相关 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <!-- spock 相关 --> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.9</version> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>1.1-groovy-2.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-spring</artifactId> <version>1.1-groovy-2.4</version> <scope>test</scope> </dependency>
3.新建基类BaseSpockSpec.groovy
package c.a.s.spock.controller import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.TestPropertySource; import spock.lang.Specification /** * 描述: spock单测基类 * 所有测试类需要继承该类 * 我们约定所有spock测试类以spec结尾 * 公司: www.tydic.com * @author ningjianguo * @time 2020/8/25 10:21 */ @SpringBootTest @TestPropertySource(locations = ["classpath:application-test.properties"]) //@ActiveProfiles("test") @AutoConfigureMockMvc class BaseSpockSpec extends Specification{ //第一个测试运行前的启动方法 def setupSpec() { println ("项目启动之前执行的,所以调用不了spring的bean"); println ("第一个测试运行前的启动方法"); } //最后一个测试运行后的清理方法 def cleanupSpec() { println ("最后一个测试运行后的清理方法"); } }
4.新建具体测试类SoSpockDemoServiceSpec.groovy
package c.a.s.spock.controller import c.a.s.api.user.bo.SoHistorySearchBO import c.a.s.api.user.service.EsSearchCountService import c.a.s.api.user.service.InitH2DataBaseService import com.alibaba.fastjson.JSONObject import com.ohaotian.plugin.base.bo.RspBaseBO import org.springframework.beans.factory.annotation.Autowired /** * 描述: 测试类 * 建议单测粒度不要过大 * 公司: www.tydic.com * @author ningjianguo * @time 2020/8/27 14:15 */ class SoSpockDemoServiceSpec extends BaseSpockSpec{ @Autowired InitH2DataBaseService initH2DataBaseService; EsSearchCountService esSearchCountService=Mock(); //每个测试运行前的启动方法 def setup(){ println("每个测试运行前的启动方法"); //如果想mock 需要在这里面引用 initH2DataBaseService.esSearchCountService=esSearchCountService //初始化sql,慎重执行 def sql="DROP TABLE IF EXISTS TEST2;\n" + "CREATE TABLE TEST2 (\n" + "\tID INT PRIMARY KEY AUTO_INCREMENT,\n" + "\tNAME VARCHAR (255)\n" + ");\n" + "INSERT INTO TEST2(NAME) VALUES('name1');\n" + "INSERT INTO TEST2(NAME) VALUES('name2');\n" + "INSERT INTO TEST2(NAME) VALUES('name3');" initH2DataBaseService.initH2(sql) } //测试feedBack def "feedBack"() { given: //入参 def querySql="select * from TEST2 where NAME='name1'"; //mock数据 List<SoHistorySearchBO> list=JSONObject.parseArray("[{\"historySearch\":\"123\",\"searchType\":\"1\"},{\"historySearch\":\"1233\",\"searchType\":\"1\"}]",SoHistorySearchBO.class) //*_代表所有入参 esSearchCountService.historySearch(*_) >> list when: //代表执行具体某个方法 RspBaseBO result=initH2DataBaseService.query(querySql) then: //断言 result.code=="0" } //每个测试运行后的清理方法 def cleanup() { println("每个测试运行后的清理方法"); } }
5.运行即可
附录:groovy简单语法
where: 以表格的形式提供测试数据集合
when: 触发行为,比如调用指定方法或函数
then: 做出断言表达式
expect: 期望的行为,when-then的精简版
given: mock单测中指定mock数据
thrown: 如果在when方法中抛出了异常,则在这个子句中会捕获到异常并返回
def setup() {} :每个测试运行前的启动方法
def cleanup() {} : 每个测试运行后的清理方法
def setupSpec() {} : 第一个测试运行前的启动方法
def cleanupSpec() {} : 最后一个测试运行后的清理方法