天天看點

Spock小結

前面的幾篇文章介紹了Spock的各種文法,和power mock的結合,以及注意事項,這篇做個總結,讓大家對Spock有個全面客觀的了解

遵循BDD模式、功能強大、語義規範、可讀性好、易于維護、富有表現力

更靈活的控制測試行為,專注代碼的邏輯測試而不是書寫文法上

用自然語言描述測試步驟(非技術人員也能看懂測試用例)

相容mock架構,可以和項目中的java單測代碼共存,降低遷移成本

IDE支援良好

Groovy動态語言,DSL,文法簡潔,約定優于配置,适合靈活開發

學習成本

Spock本身沒什麼學習成本,因為它的限制條件不多:必須有至少一個标簽、有when必有then

主要是groovy語言,如果用過的會覺得很容易(其實真的很容易),沒用過的也不用擔心,因為隻要你會java,就會groovy,花個半小時在網上看下它的基本文法即可,因為我們隻是用來寫單元測試

groovy還有一個特點就是你可以在Spock的單測代碼裡完全用java代碼寫,因為groovy完全相容java文法,或者java和groovy混着寫都沒問題,因為最終都是編譯成class執行的,JVM虛拟機不關心源檔案是什麼語言

(其實groovy的用途很廣,像我們的Jenkins裡的pipeline、Elasticsearch、hadoop架構中很多插件都是使用groovy開發的)

單測代碼執行時間

groovy文法的簡潔可以簡單了解為文法糖(其實不完全是,在jvm中執行使用的是invokeDynamic指令),文法糖會相應的增加jvm建構AST文法樹的時間

大家在運作的時候可能會注意到spock代碼的編譯要比java的單測代碼慢一些(視代碼複雜度而言,平均大概慢1-2s),但是執行的時間和java的差不多,如果對這個有要求,慎重使用,最好自己本地驗證下

Spock不支援靜态、final方法的mock

關于這一點在前面的文章裡已經講過,是以需要引入power mock,也沒必要重複造輪子

這裡要明确一點: Spock不是Mockito,雖然Spock中可以使用Mockitio的功能,但Spock不是Mockitio,是以大家要搞清楚兩者的差別,可以參考官方開發人員的解釋:

Spock小結

(https://github.com/spockframework/spock/issues/629)

因為Spock并不支援Mockito和power mock的@InjectMocks和@Mock的組合,運作時會報錯,如果你一定要使用對應的功能可以引入Mockitio為Spock專門開發的第三方工具:spock-subjects-collaborators-extension,使用Subject和@Collaborator代替@InjectMocks和@Mock

用法如下:

具體參考:

https://github.com/marcingrzejszczak/spock-subjects-collaborators-extension

我個人的建議是用PowerMockito.mock()的方式代替注解,雖沒有注解的文法簡潔,但不用再引入額外的依賴

有時候你覺得單測代碼很難寫,說明被測試的代碼本身不夠合理,需要去關注代碼本身的邏輯,設計是否合理,重構業務代碼,讓你的代碼變得容易測試

因為代碼的可測試性也是衡量代碼品質的重要标準

Spock隻是個工具,如果用它都無法解決你的單測case,那就需要把更多的注意力放在業務代碼的設計上

總之Spock不能保證讓你愛上寫單測,但至少不會反感

(完整的源碼在公衆号裡回複spock擷取)

網上關于Spock的資料過于簡單,包括官網的demo,無法解決我們項目中的複雜業務場景,需要找到一套适合自己項目的成熟解決方案

是以覺得有必要把我們項目中使用Spock的經驗分享出來,幫助大家解決實際問題或帶來一些啟發,如果你在使用過程中遇到問題可以在公衆号或我的部落格(www.javakk.com)留言交流

官網:

http://spockframework.org/

官網文檔:

http://spockframework.org/spock/docs/1.3/all_in_one.html

github:

https://github.com/spockframework/spock

代碼示例:

https://github.com/spockframework/spock-example

END -