Mockito入门学习(2)--Mock的基本使用

来源:互联网 发布:vs2010怎么编译c语言 编辑:程序博客网 时间:2024/05/21 09:40

为了方便在类中使用,可以使用java 的静态引入,将mockito中常用的方法引入到单元测试类中。

Import static org.mockito.Mockito.*;

创建Mock对象

这里将会使用List作为测试的对象,主要原因是这个类比较常用,大家对接口也都比较熟悉。

在mockito中要mock一个对象很简单,只需要调用mock(Class)方法即可。

List mockedStringList = mock(List.class);#mock object creation

除了调用mock(Class)创建mock对象,Mockito还提供使用annotation方式进行创建mock对象。对于使用annotation创建对象的方法会在以后的笔记中集中进行讲解,这里主要讨论mock对象以及基本使用。

使用Mock对象进行behavior verification

对mock对象进行行为检测,也就是查看mock对象的某些特定方法是否被使用了,以及被使用了几次。在mockito中,通过verify(T)方法来进行behavior verification。这个方法会返回T对象本身,需要紧接了调用某个特定的方法来判断这个特定的方法是否得到了调用。

@Testpublic void behaviorVerification() {    List<String> mockedStringList = mock(List.class);//mock object creation    mockedStringList.add("robin hood");//invoke add function of list    verify(mockedStringList).add("robin hood");//verify the add function is called once}

一般来说,在单元测试中基本不会手动调用一个方法(如例子中的MockedStringList.add(“robin hood”)),然后再验证这个方法被调用过。一般来说,是一个对象B存在于另外一个对象A中,当调用A对象的某个方法,如A.run(),而A.run()中又调用了B对象的B.go()方法,那么在单元测试的时候,就可以创建一个B的mock对象,并让A使用这个mock对象,然后通过调用A的方法来检测B的某个方法是否被调用了。如下面的例子,Printer.print()方法内部调用了document.getWholeFormattedContent()方法,因此可以通过检测在调用Printer.print()方法的时候document.getWholeFormattedContent()方法是否被调用过来判断Printer.print()的逻辑是否正确。

public static class Printer {    public void print(Document document) {        String documentContent = document.getWholeFormattedContent();    }}public static class Document {    public String getWholeFormattedContent() {        return "";    }}@Testpublic void behaviorVerificationInside() {    Document document = mock(Document.class);    Printer printer = new Printer();    printer.print(document);    verify(document).getWholeFormattedContent();}

verify(T)方法仅仅是进行了简单的判断,判断某个特定的方法(这个例子中是document.getWholeFormattedContent()方法)只被调用了一次。verify(T)其实是verify(T, times(1))的缩略形式。

使用Mock对象进行state verification

有些时候,在做单元测试的时候,不仅仅关心某个方法被运行了,还关心这个方法的返回值对最后结果的影响,这个时候就需要mock对象的另外一个功能了——stub。如果大家对这个概念还不是很清楚的话,可以查看下Mocktio读书笔记的第一讲,里面介绍了stub和mock的区别。

在mockito中,通过调用when(T methodCall).thenReturn(T expectedResult)来插入预定值。这个方法声明了,当methodCall被调用的时候(包含特定的参数),expectedResult会被返回,不管method内部逻辑如何。

@Testpublic void run() {    List<String> list = mock(ArrayList.class);    when(list.size()).thenReturn(5);// when list.size() is called, 5 will returned, although                                    // there is no data in the real list.    Assert.assertEquals(5, list.size());// will pass the assertion}

在上面的这个例子中,一开始mock了一个list对象,并没有往里面添加任何数据,但是通过when().thenReturn()方法,设置了一个返回值5给了list.size()方法,那么当这个mock的list对象的size()方法真的被调用的时候,数值5就会返回。这就是完成了对mock对象的插值。当然,在实际应用中一样为一个方法设置了插值,然后在手动调用这个方法,一般是为某个mock的对象方法进行插值,然后在调用其它对象方法的时候会在内部调用到mock的对象方法,这时mock对象的方法就会返回预设好的值。如下面的例子,mock了一个list,在实际操作中,并没有往list添加任何数据,只是指定了当list.indexOf(“abc”)方法被调用的时候返回数值1。然后验证container.isThere(“abc”)方法返回true,因为container.isThere()方法内部是调用了list.indexOf()来进行判断是否该元素存在的。

public static class ListContainer{    final List<String> list;    public ListContainer(List<String> list) {        this.list = list;    }    public boolean isThere(String text) {        return list.indexOf(text)>=0;    }}@Testpublic void runInside() {    List<String> list = mock(ArrayList.class);    ListContainer container = new ListContainer(list);    when(list.indexOf("abc")).thenReturn(1);    Assert.assertTrue(container.isThere("abc"));}
同步更新到WordPress
0 0
原创粉丝点击