spock
是一款基於Groovy語言的單元測試框架,其基礎也是Java
的Junit
,目前最新版已經到了2.0
,但對Groovy
和響應的Java
版本要求較高,具體信息參考:Spock 2.0 M1版本初探。spring
Mockito
是一個模擬測試框架,可讓你用優雅,簡潔的接口寫出漂亮的單元測試。Mockito可讓單元測試易於可讀,產生簡潔的校驗錯誤。TDD測試驅動開發要求咱們先寫單元測試,再寫實現代碼。在寫單元測試的過程當中,因爲各類依賴的關係致使的阻礙,咱們必需用到Mockito
相似的框架來完成資源、對象的模擬。apache
testCompile 'org.mockito:mockito-core:2.7.22' testCompile group: 'org.spockframework', name: 'spock-core', version: '1.3-groovy-2.5' testCompile group: 'org.springframework', name: 'spring-test', version: '5.1.9.RELEASE' testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3' testCompile group: 'junit', name: 'junit', version: '4.12' testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0' testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.2'
下面是演示代碼:編程
package com.FunTester.mockito.practise import org.apache.http.client.methods.HttpRequestBase import org.slf4j.Logger import spock.lang.Shared import spock.lang.Specification import static com.fun.config.Constant.SPACE_1 import static com.fun.frame.SourceCode.getLogger import static org.mockito.AdditionalAnswers.returnsFirstArg import static org.mockito.Matchers.anyInt import static org.mockito.Mockito.* class Demo extends Specification { @Shared Logger logger = getLogger(this.getClass().getName()) @Shared List listsss = mock(List) @Shared HttpRequestBase httpRequestBase = mock(HttpRequestBase.class) def setup() { logger.info("測試方法開始了") } def cleanup() { logger.info("測試方法結束了") } def setupSpec() { logger.info("測試類[${getClass().getName()}]開始了") } def cleanupSpec() { logger.info("測試類[${getClass().getName()}]結束了") } def "這是一個普通的demo"() { given:"建立一個存根list,添加一些元素" List mockedList = mock(List.class); mockedList.add("one"); mockedList.add("two"); mockedList.add("three times"); mockedList.add("three times"); mockedList.add("three times"); when(mockedList.size()).thenReturn(5); mockedList.add("3") mockedList.add("3") mockedList.add("3") mockedList.add("3") expect:"驗證屬性以及方法調用次數" 5 == mockedList.size() false == verify(mockedList, atLeastOnce()).add("one") false == verify(mockedList, times(3)).add("three times") false == verify(mockedList, atMost(4)).add("3") false == verify(mockedList, never()).add("30") } def "這是一個測試的mockito模擬方法返回"() { given: "虛擬一個迭代器對象" def iterator = mock(Iterator.class) when(iterator.next()).thenReturn("hello").thenReturn("world") expect: "測試迭代器元素拼接" "hello world" == iterator.next() + SPACE_1 + iterator.next() } def "這是一個測試,用來在對象初始化以後mock對象的"() { given: "建立對象後再Mockito" def iterator = new ArrayList() iterator.add("323") def list = spy(iterator) doReturn("fun").when(list).get(3) doReturn(3).when(list).get(0) expect: list.contains("323") "fun" == list.get(3) 3 == list.get(0) } def "這是一個測試,拋出異常的測試用例"() { given: "建立測試對象" def object = mock(ArrayList.class) when(object.get(1)).thenThrow(new IndexOutOfBoundsException("我是測試"))//只能拋出可能的拋出的異常 def re = 0 try { object.get(1) } catch (IndexOutOfBoundsException e) { re = 1 } expect: re == 1 } def "這是一個測試方法返回值的用例"() { given: def j = mock(DemoJ.class) doAnswer(returnsFirstArg()).when(j).ds(anyInt(), anyInt()) // when(list.add(anyString())).thenAnswer(returnsFirstArg()); // with then() alias: // when(list.add(anyString())).then(returnsFirstArg()); expect: 3 == j.ds(3, 32) } def "我是測試共享Mock對象的用例"() { given: when(listsss.get(anyInt())).thenReturn(3) expect: 3 == listsss.get(3) } /** * 對於未指定mock的方法,spy默認會調用真實的方法,有返回值的返回真實的返回值,而mock默認不執行,有返回值的,默認返回null */ def "spy和mock區別"() { given: def list = [1,2,3,4] def integers = spy(list) when(integers.size()).thenReturn(9) expect: integers.size() == 9 integers.get(0) == 1 } }
Mockito
的基礎功能在spock
應用仍是很是流暢的,可是一些高級語法仍是沒法使用,若是在實際項目中使用請多調研二者差異,大機率仍是要混合編程。參考文章:api
Fhaohaizi@163.com
。