利用 Spock 爲Java程序編寫單元測試

Spock是一個用於Java或者Groovy程序的測試框架。利用Groovy的語言特性,Spock能夠更加快速的編寫單元測試,也可使單元測試更加清晰、簡潔。
更詳細的介紹以及用法能夠在官方文檔上看到,下面進行一些簡單的介紹和實例演示。
官方文檔地址:http://spockframework.org/spock/docs/1.1-rc-3/index.htmlhtml

Spock 基礎介紹

簡單示例

import spock.lang.*

class MyFirstSpec extends Specification {
  def "let's try this!"() {
    expect:
    Math.max(1, 2) == 3
  }
}​

能夠看到,利用Spock測試,須要首先繼承Specification類,而後用def定義測試方法,方法名能夠用字符串來表示,能夠更好的描述被測試的方法。
想快速體驗一下Spock,能夠試試Spock Web Console,地址:https://meetspock.appspot.com/node

類變量

在測試類中定義的類變量,在每一個測試方法開始前,都會被初始化一次 def action = new Action()
若是想要在測試方法以前共享類變量,須要在變量上加上註解@Shared @Shared action = new Action()git

預約義方法

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個階段github

  1. 基本設置
  2. 執行語句
  3. 測試結果
  4. 清理設置

輸入圖片說明

代碼塊

setup 代碼塊

setup也能夠寫成given。用於初始化測試方法相關變量,環境。spring

given:
def action2 = new Action()
when 和 then 代碼塊

whenthen須要配合使用。他們表示執行語句和預期的測試結果。一個測試方法能夠包含多個when-then代碼塊。app

def "test Action getHtml2"(){
    given:
    def action2 = new Action()
    def html
    
    when:
    html = action2.getHtml('Hello World')
    
    then:
    html != null
    html == 'html:Hello World2'//與預期不符
  }

當實際結果與預期結果不一樣時,Spock會給出預期值與實際值的對比。這個對比可以十分容易地看出預期與實際的差異,這個特性很是好用框架

Condition not satisfied:

html == 'html:Hello World2'
|    |
|    false
|    1 difference (94% similarity)
|    html:Hello World(-)
|    html:Hello World(2)
html:Hello World

  at com.github.spock.test.TestAction.test Action getHtml2(TestAction.groovy:39)

若是預期測試方法會拋出異常的狀況單元測試

def "test exception throw"(){
    given:
    def action2 = new Action()
    
    when:
    action2.getException()
    
    then:
    thrown(NullPointerException)
  }
expect 代碼塊

expectwhen-then的簡化版,when-then適用於測試結果值須要知足多種條件的狀況,expect適用於測試結果值只須要知足一種條件的狀況。
示例對比:測試

def "test Action getHtml2"(){
    given:
    def action2 = new Action()
    def html
    
    when:
    html = action2.getHtml('Hello World')
    
    then:
    html!=null
    html == 'html:Hello World'
  }
def "test expect"(){
    given:
    def action2 = new Action()
    
    expect:
    'html:Hello World' == action2.getHtml('Hello World')
  }
cleanup 代碼塊

用於測試方法的釋放資源等後續操做this

setup:
def file = new File("/some/path")
file.createNewFile()

// ...

cleanup:
file?.delete()
where 代碼塊

where代碼塊放在測試方法的最後面,而且一個測試方法只能有一個where代碼塊。用於數據驅動的測試方法,準備各類測試數據。

def "test where"(){
    given:
    def action2 = new Action()
    
    expect:
    result == action2.getHtml(data)
    
    where:
    data          | result
    'Hello World' |'html:Hello World'
    'Hello World2'|'html:Hello World2'
    'Hello World3'|'html:Hello World3'
  }

Mock 測試

在默認狀況下,Spock 只能 Mock 接口,增長 cglib 依賴以後,可以 Mock 類。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    <version>3.2.4</version>
</dependency>

經過>>能夠設定對應方法模擬的返回值

Action action3 = Mock()
def "test mock"(){
    action3.getHtml(_) >> 'hello'
    
    expect:
    'hello' == action3.getHtml('666')
}

與 Spring 集成測試

與 Spring 集成須要模塊 spock-spring MAVEN 依賴示例以下:

<dependencies>
    <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.1-groovy-2.4-rc-3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.4.RELEASE</version>
        </dependency>
  </dependencies>

測試類

@ContextConfiguration(locations = "classpath:applicationContext.xml")
class TestActionWithSpring extends Specification {
  
  @Autowired
  Action action;
  
  def "test with spring"(){
    expect:
    'html:Hello World' == action.getHtml('Hello World')
  }
}

示例地址:https://github.com/ivyboy/spock-example

相關文章
相關標籤/搜索