之前写单测都是用 Junit,稍微复杂点逻辑,写起来不免很繁琐。用了 Spock 后,发现单测可以如此顺滑。
在实际应用中,需要理解 Spock 阶段和块的概念。
如图:

阶段
- Setup 初始化
- Stimulus 刺激
- Response 响应
- Cleanup 清理资源
块
Given 块
准备或定义待测试的数据或对象。
1
2
3
|
given:
def stack = new Stack()
def elem = "push me"
|
When 和 Then 块
when 和 then 块始终一起出现。他们描述了刺激和预期的反应。
简单理解就是 when 为单测逻辑,then 为单测结果,then 一般是作为断言结果存在,可省略 assert。
1
2
|
when: // 刺激
then: // 响应
|
示例:
1
2
3
4
5
6
7
|
when:
stack.push(elem)
then:
!stack.empty
stack.size() == 1
stack.peek() == elem
|
Expect 块
使用 when-then 来描述具有副作用的方法,expect 描述纯功能方法。
1
2
3
4
5
|
when:
def x = Math.max(1, 2)
then:
x == 2
|
1
2
|
expect:
Math.max(1, 2) == 2
|
Cleanup 块
清理单测所占用的资源,收尾工作。
1
2
3
4
5
6
7
8
|
given:
def file = new File("/some/path")
file.createNewFile()
// ...
cleanup:
file.delete()
|
Where 块
通过上面👆块和阶段的对应图,可以看出 where 块是放在最后的,主要用来做数据驱动的单测。
1
2
3
4
5
6
7
8
9
|
def "computing the maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a << [5, 3]
b << [1, 9]
c << [5, 9]
}
|
三组数据重复整个单测流程,私以为这是 Spock 比较优雅的部分了。
另一种写法
1
2
3
4
5
6
7
8
9
|
def "computing the maximum of two numbers"() {
expect:
Math.max(a, b) == c
where:
a | b | c
5 | 1 | 5
3 | 9 | 9
}
|
总结
上面简单介绍了块和阶段的概念,以及部分示例。后面有机会在整理数据驱动测试,Mock相关等。
参考