roupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.3</version>
</dependency>
<dependency> <!-- enables mocking of classes (in addition to interfaces) -->
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.1</version>
<scope>test</scope>
</dependency>
<dependency><!-- enables mocking of classes without default constructor (together with CGLIB) -->
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
由于spock是基于groovy语言的,所以需要创建groovy的测试源码目录:首先在test目录下创建名为groovy的目录,之后将它设为测试源码目录。
创建一个简单的类:
public class Sum {
public int sum(int first, int second) {
return first + second;
}
}
创建测试类,可以手工创建,也可以使用IDEA的辅助创建:
编写测试代码,这里我们验证一下sum返回的结果是否正确: import spock.lang.Specification
class SumTest extends Specification {
def sum = new Sum();
def "sum should return param1+param2"() {
expect:
sum.sum(1,1) == 2
}
}
运行一下测试:
至此,一个最简单的spock测试就写完了。
4.3.Spock中的概念
4.3.1.Specification
在Spock中,待测系统(system under test; SUT) 的行为是由规格(specification) 所定义的。在使用Spock框架编写测试时,测试类需要继承自Specification类。
4.3.2.Fields
Specification类中可以定义字段,这些字段在运行每个测试方法前会被重新初始化,跟放在setup()里是一个效果。
def obj = new ClassUnderSpecification()
def coll = new Collaborator()
4.3.3.Fixture Methods
预先定义的几个固定的函数,与junit或testng中类似,不多解释了
def setup() {} // run before every feature method
def cleanup() {} // run after every feature method
def setupSpec() {} // run before the first feature method
def cleanupSpec() {} // run after the last feature method
4.3.4.Feature methods
这是Spock规格(Specification)的核心,其描述了SUT应具备的各项行为。每个Specification都会包含一组相关的Feature methods,如要测试1+1是否等于2,可以编写一个函数:
def "sum should return param1+param2"() {
expect:
sum.sum(1,1) == 2
}
4.3.5.blocks
每个feature method又被划分为不同的block,不同的block处于测试执行的不同阶段,在测试运行时,各个block按照不同的顺序和规则被执行,如下图:
下面分别解释一下各个block的用途。
4.3.6.Setup Blocks
setup也可以写成given,在这个block中会放置与这个测试函数相关的初始化程序,如:
setup:
def stack = new Stack()
def elem = "push me"
一般会在这个block中定义局部变量,定义mock函数等。
4.3.7.When and Then Blocks
when与then需要搭配使用,在when中执行待测试的函数,在then中判断是否符合预期,如:
when:
stack.push(elem)
then:
!stack.empty
stack.size() == 1
stack.peek() == elem
4.3.7.1.断言
条件类似junit中的assert,就像上面的例子,在then或expect中会默认assert所有返回值是boolean型的顶级语句。如果要在其它地方增加断言,需要显式增加assert关键字,如:
def setup() {
stack = new Stack()
assert stack.empty
}
4.3.7.2.异常断言
如果要验证有没有抛出异常,可以用thrown(),如下:
when:
stack.pop()
then:
thrown(EmptyStackException)
stack.empty
要获取抛出的异常对象,可以用以下语法:
when:
stack.pop()
then:
def e = thrown(EmptyStackException)
e.cause == null
如果要验证没有抛出某种异常,可以用notThrown():
def "HashMap accepts null key"() {
setup:
def map = new HashMap()
when:
map.put(null, "elem")
then:
notThrown(NullPointerException)
}
4.3.8.Expect Blocks
expect可以看做精简版的when+then,如:
when:
def x = Math.max(1, 2)
then:
x == 2
可以简化为:
expect:
Math.max(1, 2) == 2
4.3.9.Cleanup Blocks
函数退