SpringBoot 单元测试实战(Mockito,MockBean)_第1页
SpringBoot 单元测试实战(Mockito,MockBean)_第2页
SpringBoot 单元测试实战(Mockito,MockBean)_第3页
SpringBoot 单元测试实战(Mockito,MockBean)_第4页
SpringBoot 单元测试实战(Mockito,MockBean)_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第SpringBoot单元测试实战(Mockito,MockBean)Iteratoriterator=mock(Iterator.class);

//预设当iterator调用next()时第一次返回hello,第n次都返回world

Mockito.when(iterator.next()).thenReturn("hello").thenReturn("world");

//使用mock的对象

Stringresult=iterator.next()+""+iterator.next()+""+iterator.next();

//验证结果

Assert.assertEquals("helloworldworld",result);

模拟抛出异常

@Test(expected=IOException.class)//期望报IO异常

publicvoidwhen_thenThrow()throwsIOException{

OutputStreammock=Mockito.mock(OutputStream.class);

//预设当流关闭时抛出异常

Mockito.doThrow(newIOException()).when(mock).close();

mock.close();

}

使用默认Answer模拟对象

RETURNS_DEEP_STUBS是创建mock对象时的备选参数之一

以下方法deepstubsTest和deepstubsTest2是等价的

@Test

publicvoiddeepstubsTest(){

Aa=Mockito.mock(A.class,Mockito.RETURNS_DEEP_STUBS);

Mockito.when(a.getB().getName()).thenReturn("Beijing");

Assert.assertEquals("Beijing",a.getB().getName());

@Test

publicvoiddeepstubsTest2(){

Aa=Mockito.mock(A.class);

Bb=Mockito.mock(B.class);

Mockito.when(a.getB()).thenReturn(b);

Mockito.when(b.getName()).thenReturn("Beijing");

Assert.assertEquals("Beijing",a.getB().getName());

classA{

privateBb;

publicBgetB(){

returnb;

publicvoidsetB(Bb){

this.b=b;

classB{

privateStringname;

publicStringgetName(){

returnname;

publicvoidsetName(Stringname){

=name;

publicStringgetSex(Integersex){

if(sex==1){

return"man";

}else{

return"woman";

参数匹配

@Test

publicvoidwith_arguments(){

Bb=Mockito.mock(B.class);

//预设根据不同的参数返回不同的结果

Mockito.when(b.getSex(1)).thenReturn("男");

Mockito.when(b.getSex(2)).thenReturn("女");

Assert.assertEquals("男",b.getSex(1));

Assert.assertEquals("女",b.getSex(2));

//对于没有预设的情况会返回默认值

Assert.assertEquals(null,b.getSex(0));

classB{

privateStringname;

publicStringgetName(){

returnname;

publicvoidsetName(Stringname){

=name;

publicStringgetSex(Integersex){

if(sex==1){

return"man";

}else{

return"woman";

}

匹配任意参数

Mockito.anyInt()任何int值;

Mockito.anyLong()任何long值;

Mockito.anyString()任何String值;

Mockito.any(XXX.class)任何XXX类型的值等等。

@Test

publicvoidwith_unspecified_arguments(){

Listlist=Mockito.mock(List.class);

//匹配任意参数

Mockito.when(list.get(Mockito.anyInt())).thenReturn(1);

Mockito.when(list.contains(Mockito.argThat(newIsValid()))).thenReturn(true);

Assert.assertEquals(1,list.get(1));

Assert.assertEquals(1,list.get(999));

Assert.assertTrue(list.contains(1));

Assert.assertTrue(!list.contains(3));

classIsValidextendsArgumentMatcherList{

@Override

publicbooleanmatches(Objectobj){

returnobj.equals(1)||obj.equals(2);

}

注意:使用了参数匹配,那么所有的参数都必须通过matchers来匹配

Mockito继承Matchers,anyInt()等均为Matchers方法

当传入两个参数,其中一个参数采用任意参数时,指定参数需要matchers来对比

Comparatorcomparator=mock(Comparator.class);

pare("nihao","hello");

//如果你使用了参数匹配,那么所有的参数都必须通过matchers来匹配

Mockito.verify(comparator).compare(Mockito.anyString(),Mockito.eq("hello"));

//下面的为无效的参数匹配使用

//verify(comparator).compare(anyString(),"hello");

自定义参数匹配

@Test

publicvoidargumentMatchersTest(){

//创建mock对象

ListStringmock=mock(List.class);

//argThat(MatchesTmatcher)方法用来应用自定义的规则,可以传入任何实现Matcher接口的实现类。

Mockito.when(mock.addAll(Mockito.argThat(newIsListofTwoElements()))).thenReturn(true);

Assert.assertTrue(mock.addAll(Arrays.asList("one","two","three")));

classIsListofTwoElementsextendsArgumentMatcherList

publicbooleanmatches(Objectlist)

return((List)list).size()==3;

预期回调接口生成期望值

@Test

publicvoidanswerTest(){

ListmockList=Mockito.mock(List.class);

//使用方法预期回调接口生成期望值(Answer结构)

Mockito.when(mockList.get(Mockito.anyInt())).thenAnswer(newCustomAnswer());

Assert.assertEquals("helloworld:0",mockList.get(0));

Assert.assertEquals("helloworld:999",mockList.get(999));

privateclassCustomAnswerimplementsAnswerString{

@Override

publicStringanswer(InvocationOnMockinvocation)throwsThrowable{

Object[]args=invocation.getArguments();

return"helloworld:"+args[0];

}

等价于:(也可使用匿名内部类实现)

@Test

publicvoidanswer_with_callback(){

//使用Answer来生成我们我们期望的返回

Mockito.when(mockList.get(Mockito.anyInt())).thenAnswer(newAnswerObject(){

@Override

publicObjectanswer(InvocationOnMockinvocation)throwsThrowable{

Object[]args=invocation.getArguments();

return"helloworld:"+args[0];

Assert.assertEquals("helloworld:0",mockList.get(0));

Assert.assertEquals("helloworld:999",mockList.get(999));

}

预期回调接口生成期望值(直接执行)

@Test

publicvoidtestAnswer1(){

ListStringmock=Mockito.mock(List.class);

Mockito.doAnswer(newCustomAnswer()).when(mock).get(Mockito.anyInt());

Assert.assertEquals("大于三",mock.get(4));

Assert.assertEquals("小于三",mock.get(2));

publicclassCustomAnswerimplementsAnswerString{

publicStringanswer(InvocationOnMockinvocation)throwsThrowable{

Object[]args=invocation.getArguments();

Integernum=(Integer)args[0];

if(num3){

return"大于三";

}else{

return"小于三";

}

修改对未预设的调用返回默认期望(指定返回值)

//mock对象使用Answer来对未预设的调用返回默认期望值

Listmock=Mockito.mock(List.class,newAnswer(){

@Override

publicObjectanswer(InvocationOnMockinvocation)throwsThrowable{

return999;

//下面的get(1)没有预设,通常情况下会返回NULL,但是使用了Answer改变了默认期望值

Assert.assertEquals(999,mock.get(1));

//下面的size()没有预设,通常情况下会返回0,但是使用了Answer改变了默认期望值

Assert.assertEquals(999,mock.size());

用spy监控真实对象,设置真实对象行为

@Test(expected=IndexOutOfBoundsException.class)

publicvoidspy_on_real_objects(){

Listlist=newLinkedList();

Listspy=Mockito.spy(list);

//下面预设的spy.get(0)会报错,因为会调用真实对象的get(0),所以会抛出越界异常

//Mockito.when(spy.get(0)).thenReturn(3);

//使用doReturn-when可以避免when-thenReturn调用真实对象api

Mockito.doReturn(999).when(spy).get(999);

//预设size()期望值

Mockito.when(spy.size()).thenReturn(100);

//调用真实对象的api

spy.add(1);

spy.add(2);

Assert.assertEquals(100,spy.size());

Assert.assertEquals(1,spy.get(0));

Assert.assertEquals(2,spy.get(1));

Assert.assertEquals(999,spy.get(999));

不做任何返回

@Test

publicvoidTest(){

Aa=Mockito.mock(A.class);

//void方法才能调用doNothing()

Mockito.doNothing().when(a).setName(Mockito.anyString());

a.setName("bb");

Assert.assertEquals("bb",a.getName());

classA{

privateStringname;

privatevoidsetName(Stringname){

=name;

privateStringgetName(){

returnname;

}

调用真实的方法

@Test

publicvoidTest(){

Aa=Mockito.mock(A.class);

//void方法才能调用doNothing()

Mockito.when(a.getName()).thenReturn("bb");

Assert.assertEquals("bb",a.getName());

//等价于Mockito.when(a.getName()).thenCallRealMethod();

Mockito.doCallRealMethod().when(a).getName();

Assert.assertEquals("zhangsan",a.getName());

classA{

publicStringgetName(){

return"zhangsan";

}

重置mock

@Test

publicvoidreset_mock(){

Listlist=mock(List.class);

Mockito.when(list.size()).thenReturn(10);

list.add(1);

Assert.assertEquals(10,list.size());

//重置mock,清除所有的互动和预设

Mockito.reset(list);

Assert.assertEquals(0,list.size());

}

@Mock注解

publicclassMockitoTest{

@Mock

privateListmockList;

//必须在基类中添加初始化mock的代码,否则报错mock的对象为NULL

publicMockitoTest(){

MockitoAnnotations.initMocks(this);

@Test

publicvoidAnnoTest(){

mockList.add(1);

Mockito.verify(mockList).add(1);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论