人人都说单元测试好,但是好多同学还是不愿意去写,其中一个很重要的原因就是测试代码的编写占用了太多的时间,而且测试本身也会出现bug。Spock相比JUnit有易读、简洁、自带Mock等特性,可以减少单元测试编写时间,而且bug更少,可读性更好。虽然使用的Groovy语法,但是基本兼容Java语法,使用起来没有门槛,好东西就要分享!
Spock的特性
代码易读
易读的测试用例名字,可以使用任意字符串,比如下面中test stack
易理解的代码模块:given, when, then, expect
def "test stack"() {
given:
def stack = new Stack()
when:
stack.pop()
then:
thrown(EmptyStackException)
stack.empty
}
Where支持多组参数
def "computing the maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a << [5, 3]
b << [1, 9]
c << [5, 9]
}
class MathSpec extends Specification {
def "maximum of two numbers"(int a, int b, int c) {
expect:
Math.max(a, b) == c
where:
a | b | c
1 | 3 | 3
7 | 4 | 7
0 | 0 | 0
}
}
更友好的错误信息
(把上面的用例故意改错)
class MathSpec extends Specification {
def "maximum of two numbers"(int a, int b, int c) {
expect:
Math.max(a, b) == c
where:
a | b | c
1 | 3 | 1
7 | 4 | 7
0 | 0 | 0
}
}
错误提示如下,可以看出错误信息提示很完善
Condition not satisfied:
Math.max(a, b) == c
| | | | |
3 1 3 | 1
false
Expected :1
Actual :3
Mock and stub: Interactions
Spock本身就支持mock和打桩,方便测试外部依赖的组件,JUnit还需要依赖其他Jar包,比如Mockito
def service = Mock(Service) // has start(), stop(), and doWork() methods
def app = new Application(service) // controls the lifecycle of the service
when:
app.run()
then:
with(service) {
1 * start()
1 * doWork()
1 * stop()
}
更多的运行时信息
增加一些信息,帮助单元测试运行过程定位问题
setup: "open a database connection"
// code goes here
and: "seed the customer table"
// code goes here
and: "seed the product table"
// code goes here
如何开始使用
引入Jar包
pom文件中引入依赖
org.spockframework
spock-core
1.1-groovy-2.4
test
org.codehaus.groovy
groovy-all
2.4.15
test
org.spockframework
spock-spring
1.1-groovy-2.4
test
org.codehaus.gmavenplus
gmavenplus-plugin
1.6.1
compile
compileTests
IDEA中使用
创建测试用例
第一个测试用例
常见问题
maven test命令并没有执行单元测试,而是提示No tests to run.:没有配置插件gmavenplus-plugin
参考