1. 程式人生 > 實用技巧 >spock單元測試

spock單元測試

1.spock介紹

Spock 框架是一個基於groovy語法的測試框架,由於使用groovy,所以使用起來比 junit 更加靈活,測試用例的寫法更加簡單易懂,一目瞭然

2.maven

<!-- h2database 相關  -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- spock 相關  -->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.9</version>
        </dependency>

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.1-groovy-2.4</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-spring</artifactId>
            <version>1.1-groovy-2.4</version>
            <scope>test</scope>
        </dependency>

  3.新建基類BaseSpockSpec.groovy

package c.a.s.spock.controller

import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.TestPropertySource;
import spock.lang.Specification

/**
 * 描述: spock單測基類
 * 所有測試類需要繼承該類
 * 我們約定所有spock測試類以spec結尾
 * 公司: www.tydic.com
 * @author ningjianguo
 * @time  2020/8/25 10:21
*/
@SpringBootTest
@TestPropertySource(locations = ["classpath:application-test.properties"])
//@ActiveProfiles("test")
@AutoConfigureMockMvc
class BaseSpockSpec extends  Specification{
    //第一個測試執行前的啟動方法
    def setupSpec() {
        println ("專案啟動之前執行的,所以調用不了spring的bean");
        println ("第一個測試執行前的啟動方法");
    }



    //最後一個測試執行後的清理方法
    def cleanupSpec() {
        println ("最後一個測試執行後的清理方法");
    }
}

  4.新建具體測試類SoSpockDemoServiceSpec.groovy

package c.a.s.spock.controller

import c.a.s.api.user.bo.SoHistorySearchBO
import c.a.s.api.user.service.EsSearchCountService
import c.a.s.api.user.service.InitH2DataBaseService
import com.alibaba.fastjson.JSONObject
import com.ohaotian.plugin.base.bo.RspBaseBO
import org.springframework.beans.factory.annotation.Autowired

/**
 * 描述: 測試類
 * 建議單測粒度不要過大
 * 公司: www.tydic.com
 * @author ningjianguo
 * @time  2020/8/27 14:15
*/
class SoSpockDemoServiceSpec extends BaseSpockSpec{
    @Autowired
    InitH2DataBaseService initH2DataBaseService;
    EsSearchCountService esSearchCountService=Mock();

    //每個測試執行前的啟動方法
    def setup(){
        println("每個測試執行前的啟動方法");
        //如果想mock 需要在這裡面引用
        initH2DataBaseService.esSearchCountService=esSearchCountService

        //初始化sql,慎重執行
        def sql="DROP TABLE IF EXISTS TEST2;\n" +
                "CREATE TABLE TEST2 (\n" +
                "\tID INT PRIMARY KEY AUTO_INCREMENT,\n" +
                "\tNAME VARCHAR (255)\n" +
                ");\n" +
                "INSERT INTO TEST2(NAME) VALUES('name1');\n" +
                "INSERT INTO TEST2(NAME) VALUES('name2');\n" +
                "INSERT INTO TEST2(NAME) VALUES('name3');"
        initH2DataBaseService.initH2(sql)
    }

    //測試feedBack
    def "feedBack"() {
        given:
        //入參
        def querySql="select * from TEST2 where NAME='name1'";
        //mock資料
        List<SoHistorySearchBO> list=JSONObject.parseArray("[{\"historySearch\":\"123\",\"searchType\":\"1\"},{\"historySearch\":\"1233\",\"searchType\":\"1\"}]",SoHistorySearchBO.class)
        //*_代表所有入參
        esSearchCountService.historySearch(*_) >> list

        when:
        //代表執行具體某個方法
        RspBaseBO result=initH2DataBaseService.query(querySql)

        then:
        //斷言
        result.code=="0"
    }


    //每個測試執行後的清理方法
    def cleanup() {
        println("每個測試執行後的清理方法");
    }
}

5.執行即可

附錄:groovy簡單語法

where: 以表格的形式提供測試資料集合

when: 觸發行為,比如呼叫指定方法或函式

then: 做出斷言表示式

expect: 期望的行為,when-then的精簡版

given: mock單測中指定mock資料

thrown: 如果在when方法中丟擲了異常,則在這個子句中會捕獲到異常並返回

def setup() {} :每個測試執行前的啟動方法

def cleanup() {} : 每個測試執行後的清理方法

def setupSpec() {} : 第一個測試執行前的啟動方法

def cleanupSpec() {} : 最後一個測試執行後的清理方法