如何使用 Spock 測試 Static Method

Spock 簡易使用說明

使用 Spock 來開發(fā)測試程式除了在之前的文章中提到的:可輔助 BDD 的開發(fā)流程楞艾、與 JUnit 相容及內(nèi)建 Data Driven 功能等特性之外篓冲,還有另外一項(xiàng)優(yōu)點(diǎn)是內(nèi)建了 Mock 的功能寒锚。Spock 所提供的 Mock 功能在使用上相當(dāng)?shù)暮啙崳韵率且欢畏独脑创a:

def "Spock 范例測試程式"() {
    given:
    def mockClass = Mock(ConcreteClass)
    def mockInterface1 = Mock(IInjection)
    IInjection mockInterface2 = Mock()
    Processor tester = new Processor(mockClass)

    mockInterface2.getInfo() >> { "二號測試字串" }

    when:
    tester.run(mockInterface1)

    then:
    1 * mockClass.start()
    1 * mockInterface1.getInfo() >> { "一號測試字串" }
    _ * mockClass.process(_) >> { mockInterface2 }
    1 * mockInterface2.setData(_)
    1 * mockClass.end()
}

由以上的源代碼可以看到只要使用 Mock() 方法就可以對指定的對象進(jìn)行 Mock 的程序乓旗,同時也提供二種彈性的聲明方式府蛇,一是把要 Mock 的對象傳入 Mock() 方法(第 3, 4 行),另一個方式是使用 Mock() 方法來建立實(shí)例(第 5 行)寸齐。第二種 Java-like 的語法主要是希望在編輯源代碼時 IDE 可以提供較好的支持欲诺,運(yùn)行時會以聲明的型別來判定要產(chǎn)生的 Mock 對象之 Instance。

Spock 所提供的 Mock 功能有另一個亮點(diǎn)是不僅能夠針對 Interface渺鹦,同時也可以使用在一般的 Class 上扰法。如此在進(jìn)行系統(tǒng)設(shè)計時,就可以不用遷就 “是否有辦法分開測試” 這個問題而要使用大量的 IoC 在設(shè)計之中毅厚,以致形成了過度設(shè)計的情況塞颁。在 Mock Class 前,項(xiàng)目必須要引用 cglib-nodep 和 objenesis 這二個庫吸耿,所以在 build.gradle 的 dependencies 應(yīng)該像以下所示范的內(nèi)容:

dependencies {
    testCompile 'org.codehaus.groovy:groovy-all:2.4.4'
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.objenesis:objenesis:2.2'
    testCompile 'cglib:cglib-nodep:3.1'
}

根據(jù)官方文件的說明祠锣,如果要驗(yàn)證目標(biāo) Class 與其周邊 Object 互動的過程是否符合像是序列圖所表達(dá)的設(shè)計內(nèi)容,可以使用范例程式中所示范之內(nèi)容咽安。使用的語法規(guī)格是:[互動的次數(shù)] * [互動的標(biāo)的]伴网,1 * mockClass.start() 就是驗(yàn)證 Processor.run 是否有調(diào)用 ConcreteClass.start(),而且整個 Processor.run 的運(yùn)行過程中只調(diào)用一次妆棒。

從范例程式中還可以看到澡腾,Spock 所提供的 Mock 功能,除了可以用來驗(yàn)證 Class 間互動過程糕珊,同時也具有 Stub 的能力动分。可以依據(jù)調(diào)用的內(nèi)容來提供對應(yīng)的動作红选,增加了測試程式的靈活性澜公。像范例程式中的第 8 行,當(dāng)有程式調(diào)用 mockInterface2.getInfo() 時喇肋,就會固定傳回 "二號測試字串" 的內(nèi)容坟乾。而在第 15, 16 行迹辐,是代表當(dāng) Processor.run 的運(yùn)行過程中,有調(diào)用到這二個目標(biāo)函式時所會取得的內(nèi)容甚侣。

如何 Mock 靜態(tài)方法

雖然 Spock 提供了許多優(yōu)異的特性右核,不過,美中不足的地方是目前的版本沒有辦法 Mock 靜態(tài)方法渺绒。在網(wǎng)路上看了一些討論之后,PowerMock 似乎是一個可用來搭配 Spock 解決這個問題的框架菱鸥。進(jìn)一步了解發(fā)現(xiàn) PowerMock 所提供的套件種類繁多宗兼,包含了與幾個主流的測試框架整合的功能。而如何在 Gradle 中設(shè)定對應(yīng)的套件氮采,可以讓 Spock 與 PowerMock 協(xié)同運(yùn)作會是一個門檻殷绍。

基本上要在 Spock 中使用 PowerMock 來 Mock 靜態(tài)方法,會用到 JUnit鹊漠、Mockito 和 PowerMock 這幾個框架主到,這使得在設(shè)定 build.gradle 內(nèi)容時更加的棘手。而在測試程式中要把這四個框架整合起來躯概,以便能夠達(dá)到 Mock 靜態(tài)方法的目的登钥,也是很費(fèi)心神的一件事。

目前網(wǎng)絡(luò)上查到的資訊都是片斷的娶靡,所以在這里把相關(guān)的資訊統(tǒng)整起來牧牢,做為日后研究的起點(diǎn)。以下是 build.gradle 的內(nèi)容:

apply plugin: 'java'
apply plugin: 'groovy'

dependencies {
    testCompile 'org.codehaus.groovy:groovy-all:2.4.4'
    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
    testCompile 'org.objenesis:objenesis:2.2'
    testCompile 'cglib:cglib-nodep:3.1'
    testCompile 'org.mockito:mockito-core:1.10.19'
    testCompile 'org.powermock:powermock-api-mockito:1.6.2'
    testCompile 'org.powermock:powermock-module-junit4:1.6.2'
    testCompile 'org.powermock:powermock-module-junit4-rule:1.6.2'
    testCompile 'org.powermock:powermock-classloading-xstream:1.6.2'
}

以上的套件應(yīng)該要依照所屬框架更新的狀況來調(diào)整對應(yīng)的版本編號姿锭。

在測試程式中塔鳍,如果有一個以下待測的 Class:

public class TestClass {

    public static String staticMethod() {
        return null;
    }

}

測試程式應(yīng)該像以下所示范的內(nèi)容來進(jìn)行靜態(tài)方法的測試:

import org.junit.Rule
import org.mockito.Mockito
import org.powermock.api.mockito.PowerMockito
import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.rule.PowerMockRule
import spock.lang.Specification

@PrepareForTest([TestClass.class])
class MockStaticMethodSpec extends Specification {

    @Rule
    PowerMockRule mPowerMockRule = new PowerMockRule();

    def "測試靜態(tài)方法"() {
        setup :
        PowerMockito.mockStatic(TestClass.class)

        when :
        Mockito.when(TestClass.staticMethod()).thenReturn("測試用字串")

        then :
        TestClass.staticMethod() == "測試用字串"
    }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市呻此,隨后出現(xiàn)的幾起案子轮纫,更是在濱河造成了極大的恐慌,老刑警劉巖焚鲜,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掌唾,死亡現(xiàn)場離奇詭異,居然都是意外死亡恃泪,警方通過查閱死者的電腦和手機(jī)郑兴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贝乎,“玉大人情连,你說我怎么就攤上這事±佬В” “怎么了却舀?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵虫几,是天一觀的道長。 經(jīng)常有香客問我挽拔,道長辆脸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任螃诅,我火速辦了婚禮啡氢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘术裸。我一直安慰自己倘是,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布袭艺。 她就那樣靜靜地躺著搀崭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪猾编。 梳的紋絲不亂的頭發(fā)上瘤睹,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音答倡,去河邊找鬼轰传。 笑死,一個胖子當(dāng)著我的面吹牛瘪撇,可吹牛的內(nèi)容都是我干的绸吸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼设江,長吁一口氣:“原來是場噩夢啊……” “哼锦茁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叉存,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤码俩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后歼捏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稿存,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年瞳秽,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓣履。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡练俐,死狀恐怖袖迎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤燕锥,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布辜贵,位于F島的核電站,受9級特大地震影響归形,放射性物質(zhì)發(fā)生泄漏托慨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一暇榴、第九天 我趴在偏房一處隱蔽的房頂上張望厚棵。 院中可真熱鬧,春花似錦蔼紧、人聲如沸窟感。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哈误,卻和暖如春哩至,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜜自。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工菩貌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人重荠。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓箭阶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戈鲁。 傳聞我的和親對象是個殘疾皇子仇参,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)婆殿,斷路器诈乒,智...
    卡卡羅2017閱讀 134,711評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,306評論 25 707
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,859評論 6 342
  • 本文介紹了Android單元測試入門所需了解的內(nèi)容,包括JUnit婆芦、Mockito和PowerMock的使用怕磨,怎樣...
    于衛(wèi)國閱讀 4,585評論 0 5
  • 曾走過這樣一條路,它橫臥在兩排銀杏樹間消约,平坦干凈的地面肠鲫,被稀疏的綠蔭覆蓋,一雙雙陌生的腳或粮,不停的來回走動著导饲,卻...
    竹鴻初閱讀 221評論 0 1