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
。