Java单元测试 --- Spock

/ 测试Java / 没有评论 / 2004浏览

人人都说单元测试好,但是好多同学还是不愿意去写,其中一个很重要的原因就是测试代码的编写占用了太多的时间,而且测试本身也会出现bug。Spock相比JUnit有易读、简洁、自带Mock等特性,可以减少单元测试编写时间,而且bug更少,可读性更好。虽然使用的Groovy语法,但是基本兼容Java语法,使用起来没有门槛,好东西就要分享!

Spock的特性

代码易读

易读的测试用例名字,可以使用任意字符串,比如下面中test stack 易理解的代码模块:given, when, then, expect

def "test stack"() {
    given:
    def stack = new Stack<Integer>()
    
    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文件中引入依赖

<dependencies>
    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-core</artifactId>
        <version>1.1-groovy-2.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.15</version>
        <scope>test</scope>
    </dependency>
    <!--如果是在Spring环境下测试,还需要添加一下依赖-->
    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-spring</artifactId>
        <version>1.1-groovy-2.4</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.6.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compileTests</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

IDEA中使用

img

img

常见问题

参考