• 使用Mockito进行单元测试【2】—— stub 和 高级特性[转]


    一篇中介绍了Mockito的基本信息,现在接着介绍Mockito强大的stub功能

    2. Mockito使用实例

    5. 对连续的调用进行不同的返回 (iterator-style stubbing)

    还记得在实例2中说道当我们连续两次为同一个方法使用stub的时候,他只会使用最新的一次。但是在某一个方法中我们确实有很多的调用怎么办呢?mockito当然想到这一点了:

    Java代码 复制代码 收藏代码
    1. when(mock.someMethod("some arg"))  
    2.   .thenThrow(new RuntimeException())  
    3.   .thenReturn("foo");  
    4.   
    5. //First call: throws runtime exception:  
    6. mock.someMethod("some arg");  
    7.   
    8. //Second call: prints "foo"  
    9. System.out.println(mock.someMethod("some arg"));  
    10.   
    11. //Any consecutive call: prints "foo" as well (last stubbing wins).   
    12. System.out.println(mock.someMethod("some arg"));  

    当然我们也可以将第一句写的更简单一些:

    Java代码 复制代码 收藏代码
    1. when(mock.someMethod("some arg"))  
    2.   .thenReturn("one", "two", "three");  

    参见网页例子10。

    6. 使用回调进行stub【Stubbing with callbacks】

    我们可以使用generic的Answer接口来让mock对象执行我们期望它执行的内容。比如我们可以查看调用方法的参数信息,并根据这个信息进行不同的处理,这可以使我们的stub变得十分的灵活。

    Java代码 复制代码 收藏代码
    1. when(mock.someMethod(anyString())).thenAnswer(new Answer() {  
    2.     Object answer(InvocationOnMock invocation) {  
    3.         Object[] args = invocation.getArguments();  
    4.         Object mock = invocation.getMock();  
    5.         return "called with arguments: " + args;  
    6.     }  
    7. });  
    8.   
    9. //Following prints "called with arguments: foo"  
    10. System.out.println(mock.someMethod("foo"));  

    参见网页例子11。

    7. 使用 doThrow()|doAnswer()|doNothing()|doReturn() 来 stub void方法

    void方法也需要stub?呵呵,实际生活中我们应该只会用到doThrow来模拟这个void方法出错的情况吧,anyway,mockito提供了四个方法,发挥你的想象力吧:-)

    Java代码 复制代码 收藏代码
    1. doThrow(new RuntimeException()).when(mockedList).clear();  
    2.   
    3. //following throws RuntimeException:  
    4. mockedList.clear();  

      参见网页例子12。

    8. 在真实的对象上进行spy

    spy的意思是你可以修改某个真实对象的某些方法的行为特征,而不改变他的基本行为特征,这种策略的使用跟AOP有点类似。下面举一个例子来说明:

    Java代码 复制代码 收藏代码
    1. List list = new LinkedList();  
    2. List spy = spy(list);  
    3.   
    4. //optionally, you can stub out some methods:  
    5. when(spy.size()).thenReturn(100);  
    6.    
    7. //using the spy calls <b>real</b> methods  
    8. spy.add("one");  
    9. spy.add("two");  
    10.    
    11. //prints "one" - the first element of a list  
    12. System.out.println(spy.get(0));  
    13.    
    14. //size() method was stubbed - 100 is printed  
    15. System.out.println(spy.size());  
    16.    
    17. //optionally, you can verify  
    18. verify(spy).add("one");  
    19. verify(spy).add("two"); 

    可以看到spy保留了list的大部分功能,只是将它的size方法改写了。不过spy在使用的时候有很多地方需要注意,一不小心就会导致问题,所以不到万不得已还是不要用spy。下面介绍两个spy的陷阱:

    【1】有时我们无法使用when的方式来spy,此时我们就需要使用doReturn|Answer|Throw() 等方式来进行spy了:

    Java代码 复制代码 收藏代码
    1. List list = new LinkedList();  
    2. List spy = spy(list);  
    3.   
    4. //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)  
    5. when(spy.get(0)).thenReturn("foo");  
    6.   
    7. //You have to use doReturn() for stubbing  
    8. doReturn("foo").when(spy).get(0);  

    比如我们使用when的时候实际已经调用了get(0)方法,这个时候将直接抛出异常,所以此时应该使用doReturn来进行spy

    【2】spy实际上是对对象做了一个拷贝,就像上面的,如果我们直接看list这个对象,它实际上只执行了这样一句话List list = new LinkedList();

    【3】 无法spy final方法。

    参见网页例子13。

    9. 其他高级特性

    当说到高级特性,我们就是说那些基本用不到,但是当我们想用的时候就非常顺手的功能,比如:

    # 改变没有stub方法的默认返回值  网页例子14

    # 抓取参数进行assert验证  网页例子15

    # 重置mock对象   网页例子16

    由于浙西而使用机会比较小,这里就不详述了,更多的例子还是参考网页http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html

    3.小结

    不知看了以上的内容,你是否觉得Mockito是使用mock进行单元测试的理想工具,如果是的话,就猛击

    http://code.google.com/p/mockito/的主页下载并使用吧:-)

    本文转自:http://qiuguo0205.iteye.com/blog/1456528

  • 相关阅读:
    pthread_key_t和pthread_key_create()详解
    oracle的时间
    spring加载bean报错:expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    MyBatis调用存储过程
    java的时间
    java的日期
    java中的多态
    笔记本设置wifi热点并抓包
    WiresShark使用说明
    HTTP协议概述
  • 原文地址:https://www.cnblogs.com/vvonline/p/4122991.html
Copyright © 2020-2023  润新知