赞
踩
Spock是基于JUnit的单测框架,提供一些更好的语法,结合Groovy语言,可以写出更为简洁的单测。
<!-- groovy依赖 --> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.0</version> </dependency> <!-- spock核心依赖 --> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>1.3-groovy-2.4</version> <scope>test</scope> </dependency> <!-- spring spock依赖 --> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-spring</artifactId> <version>1.3-groovy-2.4</version> <scope>test</scope> </dependency> <!-- 单元测试依赖 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency>
继承Specification
类
package com.qiang.groovy.controller
import com.qiang.groovy.controller.ConfigInfoController
import spock.lang.Specification
class ConfigInfoControllerGroovy extends Specification {
}
固定方法
/** * 在第一个测试方法开始前执行一遍 */ def setupSpec() { println "------------ setupSpec()方法 ------------" } /** * 每个测试方法开始前都会执行一遍 */ def setup() { println "------------ setup()方法 ------------" } /** * 每个测试方法后都会执行一遍 */ def cleanup() { println "------------ cleanup()方法 ------------" } /** * 最后一个测试方法后执行 */ def cleanupSpec() { println "------------ cleanupSpec()方法 ------------" }
测试例子
def "测试a>b"() {
given:
def a = new Random().nextInt(10)
def b = 2
expect:
println a
a > b
}
点击运行
测试通过
测试不通过
在where子句中以表格形式给出一系列输入输出的值,然后在expect中引用。
@Unroll
def "测试expect-where"() {
expect:
userInfoService.getById(id).getName() == name
where:
id | name
1 | "小强"
2 | "傻狗"
3 | "小猪"
}
当条件满足时,达到期望的结果。
@Unroll
@Transactional
def "测试given-when-then"() {
given:
// 数据准备
UserInfo userInfo = new UserInfo()
userInfo.setName("小强崽")
userInfo.setAsset(10000000.00)
when:
// 条件判断
boolean flag = userInfoService.save(userInfo)
then:
// 期望结果
flag
}
测试异常信息。
/**
* 模拟异常
*/
@Override
public void getExceptionMessage() {
throw new RuntimeException("模拟异常");
}
测试方法。
def "测试异常thrown"() {
when:
// 此方法会抛出RuntimeException
userInfoService.getExceptionMessage()
then:
// 接收异常
def ex = thrown(Exception)
ex.class.name == "java.lang.RuntimeException"
ex.getMessage() == "模拟异常"
}
远程调用第三方服务需要Mock挡板,避免受第三方服务的影响。
远程调用服务
package com.qiang.groovy.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.qiang.common.response.ResponseResult; import com.qiang.groovy.entity.UserInfo; import com.qiang.groovy.feign.GiteeServiceFeign; import com.qiang.groovy.service.UserInfoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.io.Serializable; import java.util.List; /** * @author 小强崽 * @create: 2021-04-11 21:31:14 * @description: 控制层 */ @RestController @RequestMapping("/user/info") public class UserInfoController { /** * 注入远程调用接口 */ @Autowired private GiteeServiceFeign giteeServiceFeign; /** * 远程调用 * * @param msg * @return */ @GetMapping("/gitee/test/feign") public ResponseResult<String> testFeign(@RequestParam("msg") String msg) { return giteeServiceFeign.testFeign(msg); } }
远程调用做挡板后,自定义挡板返回的参数即可。
package com.qiang.groovy.controller import com.qiang.common.response.ResponseResult import com.qiang.common.util.SpringContextUtil import com.qiang.groovy.feign.GiteeServiceFeign import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import spock.lang.Specification @SpringBootTest class UserInfoControllerGroovy extends Specification { @Autowired private UserInfoController userInfoController @Autowired private SpringContextUtil springContextUtil; /** * 单元测试调用第三方服务时,需要做挡板 */ def giteeServiceFeign = Mock(GiteeServiceFeign) def "测试远程调用"() { given: // 定义挡板返回的参数,(*_)为任意入参参数 giteeServiceFeign.testFeign(*_) >> ResponseResult.success() expect: userInfoController.testFeign(msg).code == result where: msg | result "msg" | "200" } /** * 每个测试方法开始前都会执行一遍 */ def setup() { // 挡板赋值 userInfoController.giteeServiceFeign = giteeServiceFeign } /** * 每个测试方法后都会执行一遍 */ def cleanup() { // 还原挡板 userInfoController.giteeServiceFeign = springContextUtil.getBean(GiteeServiceFeign.class) } }
某个测试用例失败了,却难以查到是哪个失败了,这时候,可以使用@Unroll注解,该注解会将where子句的每个测试用例转化为一个 @Test 独立测试方法来执行,这样就很容易找到错误的用例。
@Unroll
def "测试getById()"() {
expect:
userInfoService.getById(id).getName() == name
where:
id | name
1 | "小强"
2 | "傻狗"
3 | "小猪"
}
没加@Unroll之前
加了@Unroll之后
插入数据时,加上该注解测试完成会回滚数据。
作者(Author):小强崽
来源(Source):https://www.wuduoqiang.com/archives/Groovy+Spock单元测试
协议(License):署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
版权(Copyright):商业转载请联系作者获得授权,非商业转载请注明出处。 For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。