设为首页 加入收藏

TOP

使用 Spock 框架进行单元测试(四)
2017-12-07 14:22:06 】 浏览:1400
Tags:使用 Spock 框架 进行 单元 测试
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的目录,之后将它设为测试源码目录。ide-1
  • 创建一个简单的类:
    public class Sum {
        public int sum(int first, int second) {
            return first + second;
        }
    }
  • 创建测试类,可以手工创建,也可以使用IDEA的辅助创建:ide-2ide-3

    ide-4

  • 编写测试代码,这里我们验证一下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
        }  
    }
  • 运行一下测试:ide-5
  • 至此,一个最简单的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按照不同的顺序和规则被执行,如下图:

    blocks

    下面分别解释一下各个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

    函数退

    首页 上一页 1 2 3 4 5 6 下一页 尾页 4/6/6
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇源码 | 批量执行invokeAll() && .. 下一篇Spring、Spring Boot 和 TestNG ..

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目