一、什么是Spock
Spock 是一個測試框架,甚至可以說是一門語言他是基於Groovy開發的。它的語法完全遵循 BDD(行為驅動開發) 風格的結構。它是基於 Junit test runner 上開發但是又跟 Junit 完成不一樣,同時集成了像 Jmock、Mockito 等語法表達風格於一體,使得它很簡潔有很高的可讀性。
二、Spock 優缺點
-
語法清晰簡單並且有很高的可讀性
-
不好的就是需要學習下Groovy 的語法,對Maven的配置不是很友好。但是在Gradle 中可以很好的支持
三、如何使用Spock
Maven 的配置
- Gmavenplus-plugin 插件可以讓你的測試代碼支持 Groovy 語法
- Surefire 插件 測試時只執行帶有 Spec后綴的代碼,這個必須是*Spec.java 而不是 groovy
- spock-core 就是 spock 的核心包
- byte-buddy 用來做動態代理,如果你需要測試的代碼沒有實現接口。spock 無法幫你mock,當然你也可以用 cliglib 代替
聲明類

/** * * @author: serio.shi(苦參) * @create 2020/08/05 17:22 * */ public class User { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Dao 類

interface UserDao { public User get(int id); public User findByName(String name); public void createUser(User user); }
UserService 類

/** * * @author: serio.shi(苦參) * @create 2020/08/05 17:23 * */ public class UserService { private UserDao userDao; public UserService(UserDao userDao) { this.userDao = userDao; } public User findUser(int id){ return userDao.get(id); } public void createUser(User user){ User existing = userDao.findByName(user.getName()); if(existing == null){ userDao.createUser(user); } else{ throw new RuntimeException(String.format("User with name %s already exists!", user.getName())); } } }
測試 service的findUser 方法 mock dao的get 方法返回一個固定 user
是的你沒有看錯,它的方法名就是一個字符串(它有什么好處后面再講)。它的語法很簡單 given:、when:、then:、
setup 是它的元方法在測試用例執行前調用類似於 @before 。
- given 需要的一些變量參數
- when 就是需要測試的方法
- then 就是期待的結果
1 * dao.get(id) >> new User(id:id, name:"James", age:27)
表示 dao.get(id) 方法將會被調用一次,並且讓他返回 new User(id:id, name:"James", age:27) 對象。並且期待它的結果是 result.id == 1、result.name == "James"、result.age == 27
在運行測試后
從圖中我們可以看到,我們定義的方法名被打印出來。我們可以很方便的看到我們想要測試的內容成功了。
如果驗證沒有通過 Spock 將通過圖表的方式告訴你哪里出問題,並且它會幫你把兩個值的打印出來幫你做對比(經常有小伙伴寫測試用例的時候把值打印出來用肉眼來識別錯誤)。我們把期待的id改為12再來試下。
我們可以看到 Spock 提示你測試用例失敗了,你的id 是1而期待的是12,當你點擊 <Click to see difference> 的時候將會彈出一個框幫你做數據對比。簡直是開發神器啊有木有!!!
Spock 還有一個神奇的參數化測試,類似於表格的形式填入參數和期待的結果
我們先在UserService類中加上以下代碼:

Map datatable = [1:"jerry", 2:"tom", 3:"tommy", 4:"jack"] public String getUser(int id){ return datatable.get(id) }
添加測試用例:
def "spock parameterized test demo"(){ expect: service.getUser(id) == name where: "some id with name" id || name 1 || "jerry" 2 || "tom" 3 || "tommy" 4 || "jack" }
可以看到我們可以以更清晰的方式把入參跟結果描述出來,運行結果:
當前它還有很多的姿勢待我們去解鎖,本文只舉例了簡單的案例。
更多詳情點擊:http://spockframework.org/spock/docs/1.3/all_in_one.html#_introduction
四、小結
Spock 有着依賴少、運行快、語法簡單、代碼清晰等特點、本文只做簡單的舉例用於學習和記錄