Mockito图书馆

转载:https://static.javadoc.io/org.mockito/mockito-core/2.12.0/org/mockito/Mockito.html#42
org.mockito

类Mockito

  • 直接已知子类:
    BDDMockito


    公共类Mockito 
    扩展了ArgumentMatchers

    Mockito的标志

    Mockito图书馆可以模拟创建,验证和存根。

    这个javadoc内容也可以在http://mockito.org的网页上找到。所有的文档都保存在javadoc中,因为它保证了网页内容与源代码内容的一致性。即使脱机工作,它也允许直接从IDE访问文档。它激励Mockito开发人员随时随地记录他们编写的代码,每天都提交。

    内容

    0.迁移到Mockito 2 
    0.1 Mockito Android支持
    0.2免配置内联模拟
    1.让我们来验证一些行为!
    来自“简明英汉词典”有些残肢呢 
    3.参数匹配器
    4.验证确切的调用次数/至少一次/从不
    5.使用异常来替代void方法
    6.按顺序验证
    7.确保模拟中从未发生过交互
    8.查找多余的调用
    9.速记mocks创建 - @Mock注释
    10.连续调用连续调用(迭代器式stubbing)
    11.带回调的stubbing 
    12. doReturn()doThrow()doAnswer()doNothing()doCallRealMethod()方法家族
    13. 
    监视真实对象14.更改未打开的调用的默认返回值(从1.7开始)
    15.捕获进一步断言的参数(从1.8.0开始)
    16.实际部分模拟(从1.8.0开始)
    17.重置模拟(自1.8 0.0)
    18.故障处理及验证框架使用(由于1.8.0)
    19.别名为行为驱动开发(由于1.8.0)
    20串行化嘲笑(由于1.8.1)
    21.新的注释:@Captor@Spy@InjectMocks(由于1.8。 3)
    22.验证与超时(由于1.8.5)
    23的自动实例化@Spies@InjectMocks并构造注射善(由于1.9.0)
    24.一衬垫存根(由于1.9.0)
    25.验证忽略存根(从1.9.0开始)
    26.嘲弄细节(在2.2.x中得到改进)
    27.委托实际实例的调用(从1.9.5开始)
    28. MockMakerAPI(从1.9.5开始)
    29. BDD风格验证自1.10.0)
    30.间谍或嘲笑抽象类(从2011年10月1日,在2.7.13和2.7.14进一步增强)
    31. Mockito嘲笑可以在类加载器(从1.10.0)开始序列化 / 序列化
    32.更好的通用(从1.10.0开始)
    33. Mockito JUnit规则(从1.10.17开始)
    34. 打开关闭插件(从1.10.15开始)
    35.自定义验证失败消息(从2.1.0开始)
    36. Java 8 Lambda Matcher支持(自2.1.0起)
    37. Java 8自定义答案支持(自2.1.0起)
    38.元数据和通用类型保留(自2.1.0起)
    39.嘲笑最终类型,枚举和最终方法(从2.1.0开始)
    40.(* new *)提高生产力和清理测试,使用更严格的Mockito(自2. +开始)
    41.(** new **)用于框架集成的高级公共API(自2.10。+起)
    42.(** new **)用于集成的新API:收听验证开始事件(自2.11。+起)

    0. 迁移到Mockito 2

    为了继续改进Mockito,进一步提高单元测试的体验,我们希望你升级到2.1.0!Mockito遵循语义版本控制,仅在主要版本升级时才包含重大更改。在图书馆的生命周期中,突破变化是推出一系列改变现有行为甚至更改API的全新功能所必需的。有关新版本的综合指南,包括不兼容的更改,请参阅“ Mockito 2的新功能 ”wiki页面。我们希望你喜欢Mockito 2!

    0.1。Mockito Android支持

    随着Mockito版本2.6.1我们运送“原生”Android支持。要启用Android支持,请将`mockito-android`库作为依赖项添加到您的项目中。这个工件被发布到同一个Mockito组织,可以导入为Android如下:
    
     repositories {
       jcenter()
     }
     dependencies {
       testCompile "org.mockito:mockito-core:+"
       androidTestCompile "org.mockito:mockito-android:+"
     }
     
    您可以继续在常规虚拟机上运行相同的单元测试,在上面显示的“testCompile”范围内使用“mockito-core”工件。请注意,由于Android VM的限制,您无法使用Android上内联模拟器如果您在Android上遇到模拟问题,请在官方问题跟踪器上打开一个问题 请提供您正在使用的Android版本和项目的相关性。

    0.2。免配置内联模拟

    从版本2.7.6开始,我们提供了“mockito-inline”工件,可以不配置MockMaker扩展文件的情况下进行内联模拟要使用这个,添加`mockito-inline`而不是`mockito-core`神器,如下所示:
    
     repositories {
       jcenter()
     }
     dependencies {
       testCompile "org.mockito:mockito-inline:+"
     }
     
    请注意,当内联模拟功能被集成到默认模拟器中时,这个工件可能会被废除。

    有关内联模拟的更多信息,请参阅第39节

    1. 让我们验证一些行为!

    下面的例子嘲笑一个List,因为大多数人都熟悉的界面(如 add()get()clear()方法)。
    实际上,请不要模拟List类。改用真实的实例。
    
     //Let's import Mockito statically so that the code looks clearer
     import static org.mockito.Mockito.*;
    
     //mock creation
     List mockedList = mock(List.class);
    
     //using mock object
     mockedList.add("one");
     mockedList.clear();
    
     //verification
     verify(mockedList).add("one");
     verify(mockedList).clear();
     

    一旦创建,模拟将记住所有的交互。然后,您可以选择性地验证您感兴趣的任何互动。

    来自“简明英汉词典”有些残肢呢

    
     //You can mock concrete classes, not just interfaces
     LinkedList mockedList = mock(LinkedList.class);
    
     //stubbing
     when(mockedList.get(0)).thenReturn("first");
     when(mockedList.get(1)).thenThrow(new RuntimeException());
    
     //following prints "first"
     System.out.println(mockedList.get(0));
    
     //following throws runtime exception
     System.out.println(mockedList.get(1));
    
     //following prints "null" because get(999) was not stubbed
     System.out.println(mockedList.get(999));
    
     //Although it is possible to verify a stubbed invocation, usually it's just redundant
     //If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed).
     //If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.
     verify(mockedList).get(0);
     
    • 默认情况下,对于返回值的所有方法,mock将根据需要返回null,原始/原始包装器值或空集合。例如,对于int / Integer为0,对于布尔值/布尔值为false。
    • 可以覆盖桩号:例如,普通桩可以进入夹具设置,但测试方法可以覆盖它。请注意,覆盖残片是一种潜在的代码异味,指出了太多的残片
    • 一旦存留,该方法总是会返回一个存根值,而不管它被调用多少次。
    • 最后的茬更重要 - 当你多次用相同的参数扼杀相同的方法。换句话说:存根的顺序重要,但它只是很少有意义的,例如当存根完全相同的方法调用时,或者有时在使用参数匹配器时等等。

    3. 参数匹配器

    Mockito以自然的java风格验证参数值:使用equals()方法。有时,当需要额外的灵活性时,你可以使用参数匹配器:
    
     //stubbing using built-in anyInt() argument matcher
     when(mockedList.get(anyInt())).thenReturn("element");
    
     //stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
     when(mockedList.contains(argThat(isValid()))).thenReturn("element");
    
     //following prints "element"
     System.out.println(mockedList.get(999));
    
     //you can also verify using an argument matcher
     verify(mockedList).get(anyInt());
    
     //argument matchers can also be written as Java 8 Lambdas
     verify(mockedList).add(argThat(someString -> someString.length() > 5));
    
     

    参数匹配允许灵活的验证或存根。 查看更多内置匹配器和自定义参数匹配器/ hamcrest匹配器的示例。 Click here or here

    有关自定义参数匹配器的信息,请查看javadoc的ArgumentMatcher类。

    使用复杂的参数匹配是合理的。equals()与偶尔anyX()匹配使用的自然匹配风格倾向于给干净和简单的测试。有时候重构代码以允许equals()匹配甚至实现equals()方法来帮助进行测试会更好

    另外,阅读第15节或javadoc的ArgumentCaptor类。 ArgumentCaptor是参数匹配器的一个特殊的实现,捕获进一步的断言的参数值。

    参数匹配器警告:

    如果使用参数匹配器,所有参数都必须由匹配器提供。

    以下示例显示验证,但同样适用于存根:

    
       verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
       //above is correct - eq() is also an argument matcher
    
       verify(mock).someMethod(anyInt(), anyString(), "third argument");
       //above is incorrect - exception will be thrown because third argument is given without an argument matcher.
     

    匹配方法anyObject()eq() 不要返回匹配器。在内部,他们在堆栈上记录匹配器并返回一个虚拟值(通常为空)。这个实现是由于Java编译器强加的静态类型的安全性。其后果是,你不能使用anyObject()eq()验证/存根方法之外的方法。

    4. 验证调用的确切数量 / 至少x /从不

    
     //using mock
     mockedList.add("once");
    
     mockedList.add("twice");
     mockedList.add("twice");
    
     mockedList.add("three times");
     mockedList.add("three times");
     mockedList.add("three times");
    
     //following two verifications work exactly the same - times(1) is used by default
     verify(mockedList).add("once");
     verify(mockedList, times(1)).add("once");
    
     //exact number of invocations verification
     verify(mockedList, times(2)).add("twice");
     verify(mockedList, times(3)).add("three times");
    
     //verification using never(). never() is an alias to times(0)
     verify(mockedList, never()).add("never happened");
    
     //verification using atLeast()/atMost()
     verify(mockedList, atLeastOnce()).add("three times");
     verify(mockedList, atLeast(2)).add("three times");
     verify(mockedList, atMost(5)).add("three times");
    
     

    次(1)是默认值。因此明确地使用时间(1)可以省略。

    5. 使用异常来删除void方法

    
       doThrow(new RuntimeException()).when(mockedList).clear();
    
       //following throws RuntimeException:
       mockedList.clear();
     
    阅读更多关于doThrow()doAnswer()家庭在方法第12

     

    6. 依次验证

    
     // A. Single mock whose methods must be invoked in a particular order
     List singleMock = mock(List.class);
    
     //using a single mock
     singleMock.add("was added first");
     singleMock.add("was added second");
    
     //create an inOrder verifier for a single mock
     InOrder inOrder = inOrder(singleMock);
    
     //following will make sure that add is first called with "was added first, then with "was added second"
     inOrder.verify(singleMock).add("was added first");
     inOrder.verify(singleMock).add("was added second");
    
     // B. Multiple mocks that must be used in a particular order
     List firstMock = mock(List.class);
     List secondMock = mock(List.class);
    
     //using mocks
     firstMock.add("was called first");
     secondMock.add("was called second");
    
     //create inOrder object passing any mocks that need to be verified in order
     InOrder inOrder = inOrder(firstMock, secondMock);
    
     //following will make sure that firstMock was called before secondMock
     inOrder.verify(firstMock).add("was called first");
     inOrder.verify(secondMock).add("was called second");
    
     // Oh, and A + B can be mixed together at will
     
    按顺序进行验证是非常灵活的 - 您不必逐个验证所有交互,需要验证您有兴趣测试的所有交互

    另外,您可以创建一个InOrder对象,仅传递与按序验证相关的模拟。

    7. 确保模拟中从未发生过交互

    
     //using mocks - only mockOne is interacted
     mockOne.add("one");
    
     //ordinary verification
     verify(mockOne).add("one");
    
     //verify that method was never called on a mock
     verify(mockOne, never()).add("two");
    
     //verify that other mocks were not interacted
     verifyZeroInteractions(mockTwo, mockThree);
    
     

    8. 找到多余的调用

    
     //using mocks
     mockedList.add("one");
     mockedList.add("two");
    
     verify(mockedList).add("one");
    
     //following verification will fail
     verifyNoMoreInteractions(mockedList);
     
    一句警告:谁做了很多经典的一些用户,期望-运行-验证嘲讽倾向于使用verifyNoMoreInteractions()非常频繁,甚至在每个测试方法。 verifyNoMoreInteractions()不建议在每个测试方法中使用。verifyNoMoreInteractions()是交互测试工具包的一个方便的断言。只有在相关时才使用它。滥用它会导致过度指定不易维护的测试。你可以在这里找到更多的阅读 

    另请参阅never()- 它更加明确,并充分传达意图。

     

    9. 速记嘲笑创作- @Mock注释

    • 最小化重复的模拟创建代码。
    • 使测试类更具可读性。
    • 使验证错误易于阅读,因为字段名称 用于识别模拟。
    
       public class ArticleManagerTest {
    
           @Mock private ArticleCalculator calculator;
           @Mock private ArticleDatabase database;
           @Mock private UserProvider userProvider;
    
           private ArticleManager manager;
     
    重要!这需要在基类或测试运行的某个地方:
    
     MockitoAnnotations.initMocks(testClass);
     
    你可以使用内置的runner:MockitoJUnitRunner或者一个规则:MockitoRule

    在这里阅读更多: MockitoAnnotations

    10. 连续调用(迭代器式存根)

    有时我们需要为同一个方法调用存根不同的返回值/异常。典型的用例可能是嘲讽迭代器。原始版本的Mockito没有这个功能来促进简单的嘲笑。例如,而不是迭代器可以使用Iterable或只是集合。那些提供自然的方式(例如使用真正的收藏)。在极少数的情况下,连续调用可能是有用的,但是:

     

    
     when(mock.someMethod("some arg"))
       .thenThrow(new RuntimeException())
       .thenReturn("foo");
    
     //First call: throws runtime exception:
     mock.someMethod("some arg");
    
     //Second call: prints "foo"
     System.out.println(mock.someMethod("some arg"));
    
     //Any consecutive call: prints "foo" as well (last stubbing wins).
     System.out.println(mock.someMethod("some arg"));
     
    可选的,连续存根的较短版本:
    
     when(mock.someMethod("some arg"))
       .thenReturn("one", "two", "three");
     
    警告:如果不使用链接.thenReturn()调用,而是使用具有相同匹配器或参数的多个存根,则每个存根将覆盖前一个存根:
    
     //All mock.someMethod("some arg") calls will return "two"
     when(mock.someMethod("some arg"))
       .thenReturn("one")
     when(mock.someMethod("some arg"))
       .thenReturn("two")
     

    11. 与回调扼杀

    允许使用通用Answer接口存根

    还有另一个有争议的特点,最初没有包含在Mockito中。我们建议您简单地使用stubbing,thenReturn()或者 thenThrow()应该足以测试/测试任何干净简单的代码。但是,如果您确实需要使用通用的Answer接口进行存根,请使用下面的示例:

    
     when(mock.someMethod(anyString())).thenAnswer(new Answer() {
         Object answer(InvocationOnMock invocation) {
             Object[] args = invocation.getArguments();
             Object mock = invocation.getMock();
             return "called with arguments: " + args;
         }
     });
    
     //the following prints "called with arguments: foo"
     System.out.println(mock.someMethod("foo"));
     

    12. doReturn()doThrow()doAnswer()doNothing()doCallRealMethod()方法家族

    Stubbing void方法需要一个不同的方法,when(Object)因为编译器不喜欢方括号内的void方法。

    使用doThrow()时要与存根异常的无效方法:

    
       doThrow(new RuntimeException()).when(mockedList).clear();
    
       //following throws RuntimeException:
       mockedList.clear();
     

     

    您可以使用doThrow()doAnswer()doNothing()doReturn() 和doCallRealMethod()在地方与调用相应的when(),对于任何方法。这是必要的,当你

    • 存根无效的方法
    • 间谍对象的存根方法(见下文)
    • 不止一次地存根相同的方法,在测试过程中改变模拟的行为。
    但是您可能更愿意使用这些方法替代when()所有您的存根呼叫。

    阅读更多关于这些方法:

    doReturn(Object)

    doThrow(Throwable...)

    doThrow(Class)

    doAnswer(Answer)

    doNothing()

    doCallRealMethod()

    13. 窥探真实的物体

    你可以创建真实对象的间谍。当你使用间谍,那么真正的方法被调用(除非方法被扼杀)。

    真正的间谍应该谨慎地偶尔使用,例如在处理遗留代码时。

    对真实物体的窥视可能与“部分嘲讽”概念有关。 在释放1.8之前,Mockito间谍不是真正的部分嘲讽。原因是我们认为部分模拟是一种代码味道。在某些时候,我们发现了部分模拟的合法用例(第三方接口,对遗留代码进行中间重构,整篇文章就 在这里

     

    
       List list = new LinkedList();
       List spy = spy(list);
    
       //optionally, you can stub out some methods:
       when(spy.size()).thenReturn(100);
    
       //using the spy calls *real* methods
       spy.add("one");
       spy.add("two");
    
       //prints "one" - the first element of a list
       System.out.println(spy.get(0));
    
       //size() method was stubbed - 100 is printed
       System.out.println(spy.size());
    
       //optionally, you can verify
       verify(spy).add("one");
       verify(spy).add("two");
     

    关于间谍真相的重要窍门!

    1. 有时使用when(Object)吝啬的间谍是不可能或不切实际的因此,当使用间谍时,请考虑doReturnAnswerThrow()存根方法的家庭。例:
      
         List list = new LinkedList();
         List spy = spy(list);
      
         //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
         when(spy.get(0)).thenReturn("foo");
      
         //You have to use doReturn() for stubbing
         doReturn("foo").when(spy).get(0);
       
    2. Mockito *不会将调用委托给传入的实例,而是实际创建一个副本。所以如果你保留真实的实例并与之交互,不要期望被侦察者知道这些交互以及它们对实际实例状态的影响。其必然结果是,当* unstubbed *方法被调用*在间谍*,但*不上真正的实例*,你不会看到真正的实例的任何影响。
    3. 留意最后的方法。Mockito不会嘲笑最后的方法,所以底线是:当你窥探真实的物体时,你试图存根最后的方法=麻烦。你也将无法验证这些方法。

    14.更改未发布的调用的默认返回值(从1.7开始)

    您可以使用指定的策略为其返回值创建一个模拟。这是一个相当先进的功能,通常你不需要它来写出体面的测试。但是,使用遗留系统可能会有帮助

    这是默认的答案,所以只有当你不存在方法调用才会使用它

    
       Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
       Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
     

    阅读更多关于这个有趣的答案的答案RETURNS_SMART_NULLS

    15. 捕捉参数用于进一步断言(由于1.8.0)

    Mockito以自然的java风格验证参数值:使用equals()方法。这也是推荐的参数匹配方式,因为它使测试变得简单明了。但是,在某些情况下,在实际验证之后对某些论点作出断言是有帮助的。例如:
    
       ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
       verify(mock).doSomething(argument.capture());
       assertEquals("John", argument.getValue().getName());
     
    警告:建议使用ArgumentCaptor进行验证,但不要使用stubbing。使用带有stub的ArgumentCaptor可能会降低测试可读性,因为在assert(也就是验证或'then')块之外创建了捕获器。也可以减少缺陷定位,因为如果不调用stubbed方法,则不会捕获任何参数。

    ArgumentCaptor与自定义参数匹配器相关(请参阅ArgumentMatcherjavadoc )。这两种技术都可以用来确定传递给mock的某些参数。不过,ArgumentCaptor可能更适合以下情况:

    • 自定义参数匹配器不可能被重用
    • 你只需要它来断言参数值来完成验证
    自定义参数匹配器ArgumentMatcher通常更适合于存根。

    16. 真正的部分模拟(自1.8.0)

    最后,在邮件列表上进行了许多内部辩论和讨论后,部分模拟支持被添加到Mockito。以前我们把部分模拟视为代码味道。但是,我们发现了部分模拟的合法用例 - 更多阅读: 这里

    在发布之前,1.8版本 spy()并没有产生真正的部分嘲讽,这让一些用户感到困惑。阅读更多关于间谍:在这里或在javadoc的spy(Object)方法。

     

    
        //you can create partial mock with spy() method:
        List list = spy(new LinkedList());
    
        //you can enable partial mock capabilities selectively on mocks:
        Foo mock = mock(Foo.class);
        //Be sure the real implementation is 'safe'.
        //If real implementation throws exceptions or depends on specific state of the object then you're in trouble.
        when(mock.someMethod()).thenCallRealMethod();
      
    像往常一样,您将阅读部分模拟警告:面向对象的编程通过将复杂性划分为单独的,特定的SRPy对象来解决更复杂的问题。部分模拟如何适应这种模式?那么,它只是不...部分模拟通常意味着复杂性已被移动到同一个对象上的不同方法。在大多数情况下,这不是您想要设计应用程序的方式。

    但是,有些情况下,部分模拟会变得很方便:处理不能轻易更改的代码(第三方接口,传统代码的临时重构等)。但是,我不会使用部分模拟来实现新的,测试驱动的,设计的代码。

    17. 重新模拟(从1.8.0开始)

    智能Mockito用户很难使用这个功能,因为他们知道这可能是一个糟糕的测试的迹象。通常情况下,你不需要重置你的模拟,只是为每个测试方法创建新的模拟。

    不要reset()考虑写一些简单,小而重点明确的测试方法,而不要考虑冗长的,过度规定的测试。 第一个潜在的代码气味正reset()处于测试方法的中间。这可能意味着你测试太多了。按照你的测试方法的低语:“请保持我们的小而专注于单一的行为”。在mockito邮件列表上有几个线程。

    我们添加reset()方法的唯一原因是使用容器注入的模拟工作成为可能。有关更多信息,请参阅FAQ(此处)。

    不要伤害你自己 reset()在测试方法的中间是一个代码气味(你可能测试太多)。

    
       List mock = mock(List.class);
       when(mock.size()).thenReturn(10);
       mock.add(1);
    
       reset(mock);
       //at this point the mock forgot any interactions & stubbing
     

    18. 故障排除和验证框架使用(从1.8.0开始)

    首先,如果遇到任何问题,我建议您阅读Mockito FAQ:https: //github.com/mockito/mockito/wiki/FAQ

    如有疑问,您也可以发送到mockito邮件列表:http: //groups.google.com/group/mockito

    接下来,您应该知道Mockito会验证您是否始终正确使用它但是,有一个问题,所以请阅读javadocvalidateMockitoUsage()

    19. 行为驱动开发的别名(自1.8.0开始)

    行为驱动写作测试的开发风格使用/ / 给/ / / /然后评论作为您的测试方法的基本部分。这正是我们如何编写测试的结果,我们热烈鼓励您这样做!

    在这里开始了解BDD:http//en.wikipedia.org/wiki/Behavior_Driven_Development

    问题是当前stubbing api与正则表达式的时候,如果没有很好地集成//给定// // //然后评论。这是因为stubbing属于测试的给定组件,而不属于测试的when组件。因此,BDDMockito类引入了一个别名,以便您用BDDMockito.given(Object)方法存根方法调用现在它与BDD风格测试特定组件非常好地整合

    以下是测试的样子:

    
     import static org.mockito.BDDMockito.*;
    
     Seller seller = mock(Seller.class);
     Shop shop = new Shop(seller);
    
     public void shouldBuyBread() throws Exception {
       //given
       given(seller.askForBread()).willReturn(new Bread());
    
       //when
       Goods goods = shop.buyBread();
    
       //then
       assertThat(goods, containBread());
     }
     

    20.可串行化的模拟(自1.8.1开始)

    嘲笑可以被序列化。有了这个特性,你可以在需要依赖的地方使用模拟器来进行序列化。

    警告:这应该很少用于单元测试。

    该行为是针对具有不可靠外部依赖性的BDD规范的特定用例实现的。这是在Web环境中,来自外部依赖项的对象正在被序列化以在层之间传递。

    要创建可串行化的模拟使用MockSettings.serializable()

    
       List serializableMock = mock(List.class, withSettings().serializable());
     

    模拟可以被序列化,假设所有正常的 序列化要求都得到了这个类的满足。

    因为间谍(...)方法没有一个接受MockSettings的重载版本,所以制作一个真正的对象间谍序列化是一个更多的努力。不用担心,你几乎不会使用它。

    
     List<Object> list = new ArrayList<Object>();
     List<Object> spy = mock(ArrayList.class, withSettings()
                     .spiedInstance(list)
                     .defaultAnswer(CALLS_REAL_METHODS)
                     .serializable());
     

    21.新的注释:@Captor, @Spy, @InjectMocks(由于1.8.3)

    版本1.8.3带来新的注释,有时可能会有所帮助:

    • Captor简化了创建ArgumentCaptor - 当捕获的参数是一个令人讨厌的泛型类,并且您希望避免编译器警告时,它非常有用
    • Spy- 你可以用它来代替spy(Object)
    • InjectMocks- 将模拟或间谍字段自动注入到测试对象中。

    请注意@ InjectMocks也可以和@ Spy注解结合使用,这意味着Mockito会将mock注入到被测试的部分模拟中。这种复杂性是你仅仅使用部分模拟作为最后手段的另一个很好的理由。关于部分嘲讽,请参阅第16点。

    所有新的注释*仅*处理MockitoAnnotations.initMocks(Object)就像为@ Mock注释您可以使用内置的亚军:MockitoJUnitRunner或规则: MockitoRule

     

    22. 超时验证(自1.8.5开始)

    允许超时验证。它会导致验证等待指定的时间段进行期望的交互,而不是立即失败,如果还没有发生。可能对并发条件下的测试有用。

    这个功能应该很少使用 - 找出测试你的多线程系统的更好方法。

    尚未实施以使用InOrder验证。

    例子:

     

    
       //passes when someMethod() is called within given time span
       verify(mock, timeout(100)).someMethod();
       //above is an alias to:
       verify(mock, timeout(100).times(1)).someMethod();
    
       //passes when someMethod() is called *exactly* 2 times within given time span
       verify(mock, timeout(100).times(2)).someMethod();
    
       //passes when someMethod() is called *at least* 2 times within given time span
       verify(mock, timeout(100).atLeast(2)).someMethod();
    
       //verifies someMethod() within given time span using given verification mode
       //useful only if you have your own custom verification modes.
       verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
     

    23. 自动实例化@Spies, @InjectMocks构造注射善(由于1.9.0)

    Mockito现在将尝试实例化@ SpyInjectMocks使用构造函数注入,setter注入或字段注入来实例化@ 字段

    要利用此功能,您需要使用的优势MockitoAnnotations.initMocks(Object)MockitoJUnitRunner 或MockitoRule

    阅读更多关于可用的技巧和javadoc中的注入规则 InjectMocks

    
     //instead:
     @Spy BeerDrinker drinker = new BeerDrinker();
     //you can write:
     @Spy BeerDrinker drinker;
    
     //same applies to @InjectMocks annotation:
     @InjectMocks LocalPub;
     

    24. 单线存根(自1.9.0开始)

    Mockito现在可以让你创建嘲讽时。基本上,它允许在一行代码中创建一个存根。这可以有助于保持测试代码的清洁。例如,一个无聊的存根可以在测试中的字段初始化时创建和存根:

    
     public class CarTest {
       Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();
    
       @Test public void should... {}
     

    25. 验证忽略存根(从1.9.0开始)

    为了验证,Mockito现在允许忽略存根。有时加上verifyNoMoreInteractions()或验证时有用inOrder()有助于避免冗余验证,通常我们对验证存根不感兴趣。

    警告ignoreStubs()可能导致过度使用verifyNoMoreInteractions(ignoreStubs(...)); 请记住,Mockito不建议轰炸每个测试与verifyNoMoreInteractions() javadoc概述的原因verifyNoMoreInteractions(Object...)

    一些例子:

    
     verify(mock).foo();
     verify(mockTwo).bar();
    
     //ignores all stubbed methods:
     verifyNoMoreInteractions(ignoreStubs(mock, mockTwo));
    
     //creates InOrder that will ignore stubbed
     InOrder inOrder = inOrder(ignoreStubs(mock, mockTwo));
     inOrder.verify(mock).foo();
     inOrder.verify(mockTwo).bar();
     inOrder.verifyNoMoreInteractions();
     

    高级的例子和更多的细节可以在javadoc中找到 ignoreStubs(Object...)

    26. 嘲弄细节(在2.2.x中改进)

    Mockito提供API来检查模拟对象的细节。这个API对高级用户和模拟框架集成商很有用。

    
       //To identify whether a particular object is a mock or a spy:
       Mockito.mockingDetails(someObject).isMock();
       Mockito.mockingDetails(someObject).isSpy();
    
       //Getting details like type to mock or default answer:
       MockingDetails details = mockingDetails(mock);
       details.getMockCreationSettings().getTypeToMock();
       details.getMockCreationSettings().getDefaultAnswer();
    
       //Getting interactions and stubbings of the mock:
       MockingDetails details = mockingDetails(mock);
       details.getInteractions();
       details.getStubbings();
    
       //Printing all interactions (including stubbing, unused stubs)
       System.out.println(mockingDetails(mock).printInvocations());
     
    欲了解更多信息,请参阅javadoc MockingDetails

    27. 委托实际实例(从1.9.5开始)

    对于使用通常的间谍API 很难嘲笑或间谍的对象的间谍或部分嘲笑是有用的自从Mockito 1.10.11之后,代表可能会或可能不会与模拟类型相同。如果类型不同,则需要在委托类型上找到匹配的方法,否则抛出异常。这个功能的可能用例:

    • 最后的课程,但有一个接口
    • 已经自定义代理对象
    • 使用finalize方法的特殊对象,即避免执行2次

    与普通间谍的区别:

    • 常规spy(spy(Object))包含spied实例的所有状态,并且在spy上调用方法。侦察实例只用于模拟创建从状态复制。如果你对一个普通间谍调用一个方法,并且在内部调用这个间谍的其他方法,那么这些调用就会被记住进行验证,并且可以被有效地删除。
    • 委托的模拟只是将所有方法委托给委托。随着方法的委托,委托一直在使用。如果你调用了一个模拟的方法,委托它在内部调用其他方法,这些调用不会记住验证,存根也不会影响他们。委托模拟不如常规间谍那么强大,但是当不能创建常规间谍时,它是有用的。

    在文档中查看更多信息AdditionalAnswers.delegatesTo(Object)

    28. MockMakerAPI(自1.9.5以来)

    受谷歌Android家伙的要求和补丁的驱动,Mockito现在提供了一个扩展点,允许替换代理生成引擎。默认情况下,Mockito使用Byte Buddy 创建动态代理。

    扩展点是为了扩展Mockito的高级用户。例如,现在可以使用针对的Mockito Android的测试与帮助dexmaker

    欲了解更多细节,动机和例子请参阅文档MockMaker

    29. BDD风格验证(从1.10.0开始)

    通过启动验证与BDD启用行为驱动开发(BDD)风格的验证,然后关键字。
    
     given(dog.bark()).willReturn(2);
    
     // when
     ...
    
     then(person).should(times(2)).ride(bike);
     
    有关更多信息和示例,请参阅BDDMockito.then(Object)}

    30. 侦察或嘲笑抽象类(自2011年10月1日起,在2.7.13和2.7.14中进一步加强)

    现在可以方便地监视抽象类。请注意,过度使用间谍暗示代码设计的气味(见spy(Object))。

    以前,间谍只能在对象的实例上进行。新的API可以在创建模拟实例时使用构造函数。这对模拟抽象类特别有用,因为用户不再需要提供抽象类的实例。目前只支持无参数的构造函数,请告诉我们是否不够用。

    
     //convenience API, new overloaded spy() method:
     SomeAbstract spy = spy(SomeAbstract.class);
    
     //Mocking abstract methods, spying default methods of an interface (only available since 2.7.13)
     Function<foo, bar=""> function = spy(Function.class);
    
     //Robust API, via settings builder:
     OtherAbstract spy = mock(OtherAbstract.class, withSettings()
        .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
    
     //Mocking an abstract class with constructor arguments (only available since 2.7.14)
     SomeAbstract spy = mock(SomeAbstract.class, withSettings()
       .useConstructor("arg1", 123).defaultAnswer(CALLS_REAL_METHODS));
    
     //Mocking a non-static inner abstract class:
     InnerAbstract spy = mock(InnerAbstract.class, withSettings()
        .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
     
    欲了解更多信息,请参阅MockSettings.useConstructor(Object...)

    31. Mockito嘲笑可以通过类加载器序列化 / 序列化(从1.10.0开始)

    Mockito在类加载器中引入序列化。与任何其他形式的序列化一样,模拟层次结构中的所有类型都必须可序列化,包含的答案。由于这种序列化模式需要相当多的工作,这是一个选择性的设置。
    
     // use regular serialization
     mock(Book.class, withSettings().serializable());
    
     // use serialization across classloaders
     mock(Book.class, withSettings().serializable(ACROSS_CLASSLOADERS));
     
    欲了解更多详情,请参阅MockSettings.serializable(SerializableMode)

    32. 更好的通用支持与深存根(自1.10.0)

    如果在课堂上可以获得一般信息,则深度桩技术已得到改进。这意味着类似这样的类可以使用而不必模拟行为。
    
     class Lines extends List<Line> {
         // ...
     }
    
     lines = mock(Lines.class, RETURNS_DEEP_STUBS);
    
     // Now Mockito understand this is not an Object but a Line
     Line line = lines.iterator().next();
     
    请注意,在大多数情况下,模拟返回模拟是错误的。

    33. Mockito JUnit规则(从1.10.17开始)

    Mockito现在提供了一个JUnit规则。直到现在JUnit中有两种方法来初始化通过注释的Mockito如注释字段,等。 @Mock@Spy@InjectMocks 现在你可以选择使用一个规则:
    
     @RunWith(YetAnotherRunner.class)
     public class TheTest {
         @Rule public MockitoRule mockito = MockitoJUnit.rule();
         // ...
     }
     
    更多信息请参阅MockitoJUnit.rule()

    34. 交换机关闭的插件(15年10月1日以来)

    一个孵化功能使得mockito可以切换mockito插件。更多信息在这里PluginSwitch

    35. 自定义验证失败消息(从2.1.0开始)

    如果验证失败,允许指定要打印的自定义消息。

    例子:

     

    
    
     // will print a custom message on verification failure
     verify(mock, description("This will print on failure")).someMethod();
    
     // will work with any verification mode
     verify(mock, times(2).description("someMethod should be called twice")).someMethod();
     

    36. Java 8 Lambda Matcher支持(从2.1.0开始)

    您可以使用Java 8 lambda表达式ArgumentMatcher来减少依赖关系ArgumentCaptor如果您需要验证模拟函数调用的输入是否正确,那么您通常会使用ArgumentCaptor找到使用的操作数,然后对其执行后续的断言。虽然对于复杂的例子这可能是有用的,它也是啰嗦。

    写一个lambda来表示匹配是相当容易的。当你的函数的参数和argThat结合使用的时候,它会作为一个强类型的对象传递给ArgumentMatcher,所以可以对它做任何事情。

    例子:

     

    
    
     // verify a list only had strings of a certain length added to it
     // note - this will only compile under Java 8
     verify(list, times(2)).add(argThat(string -> string.length() < 5));
    
     // Java 7 equivalent - not as neat
     verify(list, times(2)).add(argThat(new ArgumentMatcher(){
         public boolean matches(String arg) {
             return arg.length() < 5;
         }
     }));
    
     // more complex Java 8 example - where you can specify complex verification behaviour functionally
     verify(target, times(1)).receiveComplexObject(argThat(obj -> obj.getSubObject().get(0).equals("expected")));
    
     // this can also be used when defining the behaviour of a mock under different inputs
     // in this case if the input list was fewer than 3 items the mock returns null
     when(mock.someMethod(argThat(list -> list.size()<3))).willReturn(null);
     

    37. Java 8自定义答案支持(从2.1.0开始)

    由于Answer接口只有一个方法,所以已经可以在非常简单的情况下使用lambda表达式在Java 8中实现它。您需要使用方法调用的参数的次数越多,您需要更多地对参数进行类型转换InvocationOnMock

    例子:

     

    
     // answer by returning 12 every time
     doAnswer(invocation -> 12).when(mock).doSomething();
    
     // answer by using one of the parameters - converting into the right
     // type as your go - in this case, returning the length of the second string parameter
     // as the answer. This gets long-winded quickly, with casting of parameters.
     doAnswer(invocation -> ((String)invocation.getArgument(1)).length())
         .when(mock).doSomething(anyString(), anyString(), anyString());
     
    为了方便起见,可以将使用方法调用参数的自定义答案/操作编写为Java 8 lambda表达式。即使在Java 7中,基于类型化界面的这些自定义答案也可以减少样板。特别是,这种方法将使测试使用回调函数更容易。方法answeranswerVoid 可用于创建答案。他们依赖于相关的答案接口,org.mockito.stubbing最多支持5个参数。

    例子:

     

    
    
     // Example interface to be mocked has a function like:
     void execute(String operand, Callback callback);
    
     // the example callback has a function and the class under test
     // will depend on the callback being invoked
     void receive(String item);
    
     // Java 8 - style 1
     doAnswer(AdditionalAnswers.<string,callback>answerVoid((operand, callback) -> callback.receive("dummy"))
         .when(mock).execute(anyString(), any(Callback.class));
    
     // Java 8 - style 2 - assuming static import of AdditionalAnswers
     doAnswer(answerVoid((String operand, Callback callback) -> callback.receive("dummy"))
         .when(mock).execute(anyString(), any(Callback.class));
    
     // Java 8 - style 3 - where mocking function to is a static member of test class
     private static void dummyCallbackImpl(String operation, Callback callback) {
         callback.receive("dummy");
     }
    
     doAnswer(answerVoid(TestClass::dummyCallbackImpl)
         .when(mock).execute(anyString(), any(Callback.class));
    
     // Java 7
     doAnswer(answerVoid(new VoidAnswer2<string, callback="">() {
         public void answer(String operation, Callback callback) {
             callback.receive("dummy");
         }})).when(mock).execute(anyString(), any(Callback.class));
    
     // returning a value is possible with the answer() function
     // and the non-void version of the functional interfaces
     // so if the mock interface had a method like
     boolean isSameString(String input1, String input2);
    
     // this could be mocked
     // Java 8
     doAnswer(AdditionalAnswers.<boolean,string,string>answer((input1, input2) -> input1.equals(input2))))
         .when(mock).execute(anyString(), anyString());
    
     // Java 7
     doAnswer(answer(new Answer2<string, string,="" string="">() {
         public String answer(String input1, String input2) {
             return input1 + input2;
         }})).when(mock).execute(anyString(), anyString());
     

    38. 元数据和通用类型保留(从2.1.0开始)

    Mockito现在保留对嘲笑的方法和类型以及通用元数据的注释。以前,模拟类型不保留对类型的注释,除非它们是显式继承的,并且永远不会在方法上保留注释。因此,现在下列条件成立:

    
     @MyAnnotation
      class Foo {
        List<String> bar() { ... }
      }
    
      Class<?> mockType = mock(Foo.class).getClass();
      assert mockType.isAnnotationPresent(MyAnnotation.class);
      assert mockType.getDeclaredMethod("bar").getGenericReturnType() instanceof ParameterizedType;
     

    当使用Java 8时,Mockito现在也保留了类型注释。这是默认行为,如果使用替代方法可能不会成立MockMaker

    39. 嘲笑最终类型,枚举和最终方法(从2.1.0开始)

    Mockito现在提供了一个模拟Incubating最终类和方法的可选支持。这是一个奇妙的改进,证明了Mockito对于改善测试体验的永恒追求。我们的抱负是Mockito“最后的课程和方法”。以前他们被认为是unmockable,防止用户嘲笑。我们已经开始讨论如何使这个功能默认启用。目前,该功能仍然是可选的,因为我们等待来自社区的更多反馈。

    此功能默认关闭,因为它基于完全不同的嘲笑机制,需要来自社区的更多反馈。

    这个替代的模拟器使用Java Instrumentation API和子类的组合,而不是创建一个新的类来表示一个模拟。这样,就可以模拟最终的类型和方法。

    这个模拟器默认关闭,因为它是基于完全不同的嘲弄机制,需要来自社区的更多反馈。它可以通过mockito扩展机制显式激活,只需在类路径中创建一个/mockito-extensions/org.mockito.plugins.MockMaker 包含该值的文件即可mock-maker-inline

    为了方便起见,Mockito团队在模拟器制造商预先配置的地方提供了一个神器。在您的项目中包含mockito-inline工件,而不是使用 mockito-core工件请注意,一旦嘲笑最终的类和方法被整合到默认的模拟器中,这个工件可能会被终止。

    关于这个模拟器的一些值得注意的笔记:

    • 嘲笑最终的类型和枚举是不符合模拟设置,如:
      • 明确的序列化支持 withSettings().serializable()
      • 额外的接口 withSettings().extraInterfaces()
    • 有些方法不能被嘲弄
      • 包的可见方法 java.*
      • native 方法
    • 这个模拟器是围绕Java代理运行时附件设计的; 这需要一个兼容的JVM,它是JDK(或Java 9 VM)的一部分。当在Java 9之前的非JDK虚拟机上运行时,可以 在启动JVM时使用参数手动添加Byte Buddy Java代理程序jar-javaagent

    如果你对这个功能的更多细节感兴趣,请阅读javadoc org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker

    40. (*新*)提高生产力和清洁测试与“更严格”Mockito(自2 + +)

    要快速了解“更严格”的Mockito如何使您的工作效率更高,并使测试更加清洁,请参阅: Mockito默认是一个“松散”的嘲讽框架。嘲笑可以在没有预先设定任何期望的情况下进行互动。这是有意的,它通过强迫用户明确他们想要存根/验证的内容来提高测试的质量。它也非常直观,易于使用,并与“给定”,“当时”,“那么”干净的测试代码模板很好地融合。这与过去的经典嘲讽框架不同,默认情况下它们是“严格的”。

    默认情况下,“松散”使得Mockito测试有时难以调试。在某些情况下,错误配置的桩(如使用错误的参数)会强制用户使用调试器运行测试。理想情况下,测试失败是显而易见的,不需要调试器来确定根本原因。从版本2.1开始,Mockito已经获得了将框架推向“严格”的新功能。我们希望Mockito能够提供出色的可调试性,同时不会失去其核心嘲笑风格,并针对直观性,清晰度和清晰的测试代码进行了优化。

    帮助Mockito!尝试新功能,给我们反馈,参加GitHub 第769期关于Mockito严格性的讨论 

    41. (** **新)先进的架构整合公共API(自2.10。+)

    在2017年夏季,我们决定Mockito 应该 为高级框架集成提供更好的API 新的API不适用于想要编写单元测试的用户。它旨在用于其他测试工具和模拟框架,需要扩展或包装Mockito一些自定义的逻辑。在设计和实施过程(问题1110)期间,我们已经开发并更改了以下公共API元素:
    • 新增功能MockitoPlugins- 使框架集成商可以访问默认的Mockito插件。当需要实现自定义插件(如MockMaker 将某些行为委托给默认的Mockito实现)时非常有用。
    • 新建MockSettings.build(Class)- 创建Mockito稍后使用的模拟设置的不可变视图。用于创建调用InvocationFactory或实现自定义时MockHandler
    • 新建MockingDetails.getMockHandler()- 其他框架可以使用模拟处理程序以编程方式模拟模拟对象上的调用。
    • 新建MockHandler.getMockSettings()- 有用的获取模拟对象创建的设置。
    • 新建InvocationFactory- 提供创建Invocation对象实例的方法对于需要以编程方式模拟模拟对象的方法调用的框架集成非常有用。
    • 新建MockHandler.getInvocationContainer()- 提供对没有方法的调用容器对象(标记接口)的访问。容器需要隐藏内部实现,并避免泄漏到公共API。
    • 改变Stubbing- 它现在扩展Answer接口。它是向后兼容的,因为存根接口不可扩展(请参阅NotExtensible)。这个改变对我们的用户应该是无缝的。
    • 弃用InternalMockHandler- 为了适应API的变化,我们需要弃用这个接口。界面总是被记录为内部的,我们没有证据表明它被社区使用。弃用应该完全无缝的为我们的用户。
    • NotExtensible - 公共注释,指示用户不应该提供给定类型的自定义实现。帮助框架集成商和我们的用户了解如何安全地使用Mockito API。
    你有反馈吗?请在第1110期发表评论

    42. (** new **)用于集成的新API:收听验证开始事件(自2.11。+起)

    Spring Boot 等框架集成需要公共API来解决双代理用例(问题1191)。我们补充说:
    • 字段细节

      • RETURNS_DEFAULTS

        public static final  Answer < Object > RETURNS_DEFAULTS
        Answer每个模拟的默认值如果模拟不被扼杀。通常它只是返回一些空的值。

        Answer 可以用来定义未打开的调用的返回值。

        此实现首先尝试全局配置,如果没有全局配置,则将使用返回零,空集合,空值等的默认答案。

      • RETURNS_SMART_NULLS

        public static final  Answer: < Object > RETURNS_SMART_NULLS
        可选Answer用于mock(Class, Answer)

        Answer 可以用来定义未打开的调用的返回值。

        这个实现在处理遗留代码时会很有帮助。未被拼接的方法通常返回null。如果你的代码使用了一个未经调用的调用返回的对象,你将得到一个NullPointerException异常。Answer的这个实现返回SmartNull而不是null。 SmartNull比NPE提供更好的异常消息,因为它指出了未调用方法被调用的行。你只需点击堆栈跟踪。

        ReturnsSmartNulls首先尝试返回普通的值(零,空集合,空字符串等),然后尝试返回SmartNull。如果返回类型是final,则null返回plain 

        ReturnsSmartNulls 将可能是Mockito 3.0.0中的默认返回值策略

        例:

        
           Foo mock = mock(Foo.class, RETURNS_SMART_NULLS);
        
           //calling unstubbed method here:
           Stuff stuff = mock.getStuff();
        
           //using object returned by unstubbed call:
           stuff.doSomething();
        
           //Above doesn't yield NullPointerException this time!
           //Instead, SmartNullPointerException is thrown.
           //Exception's cause links to unstubbed mock.getStuff() - just click on the stack trace.
         
      • RETURNS_MOCKS

        public static final  Answer: < Object > RETURNS_MOCKS
        可选Answer用于mock(Class, Answer)

        Answer 可以用来定义未打开的调用的返回值。

        这个实现在处理遗留代码时会很有帮助。

        ReturnsMocks首先尝试返回普通的值(零,空集合,空字符串等),然后尝试返回模拟。如果返回类型不能被模拟(例如final),则null返回plain 

         

      • RETURNS_DEEP_STUBS

        public static final  Answer: < Object > RETURNS_DEEP_STUBS
        可选Answer用于mock(Class, Answer)

        显示深度存根工作原理的示例:

        
           Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS);
        
           // note that we're stubbing a chain of methods here: getBar().getName()
           when(mock.getBar().getName()).thenReturn("deep");
        
           // note that we're chaining method calls: getBar().getName()
           assertEquals("deep", mock.getBar().getName());
         

         

        警告: 常规清洁代码很少需要此功能!将其留作遗留代码。嘲讽一个嘲讽返回一个模拟,返回一个模拟,(...),返回一些有意义的提示,违反得墨忒耳法或嘲弄价值对象(一个众所周知的反模式)。

        我有一天在网上看到了很好的报价:每次模拟回来模拟一个仙女死亡

        请注意,这个答案将返回与存根相匹配的现有模拟。这种行为对于深存根是可以的,并且允许验证在链的最后模拟上工作。

        
           when(mock.getBar(anyString()).getThingy().getName()).thenReturn("deep");
        
           mock.getBar("candy bar").getThingy().getName();
        
           assertSame(mock.getBar(anyString()).getThingy().getName(), mock.getBar(anyString()).getThingy().getName());
           verify(mock.getBar("candy bar").getThingy()).getName();
           verify(mock.getBar(anyString()).getThingy()).getName();
         

         

        验证只适用于链中的最后一个模拟。您可以使用验证模式。

        
           when(person.getAddress(anyString()).getStreet().getName()).thenReturn("deep");
           when(person.getAddress(anyString()).getStreet(Locale.ITALIAN).getName()).thenReturn("deep");
           when(person.getAddress(anyString()).getStreet(Locale.CHINESE).getName()).thenReturn("deep");
        
           person.getAddress("the docks").getStreet().getName();
           person.getAddress("the docks").getStreet().getLongName();
           person.getAddress("the docks").getStreet(Locale.ITALIAN).getName();
           person.getAddress("the docks").getStreet(Locale.CHINESE).getName();
        
           // note that we are actually referring to the very last mock in the stubbing chain.
           InOrder inOrder = inOrder(
               person.getAddress("the docks").getStreet(),
               person.getAddress("the docks").getStreet(Locale.CHINESE),
               person.getAddress("the docks").getStreet(Locale.ITALIAN)
           );
           inOrder.verify(person.getAddress("the docks").getStreet(), times(1)).getName();
           inOrder.verify(person.getAddress("the docks").getStreet()).getLongName();
           inOrder.verify(person.getAddress("the docks").getStreet(Locale.ITALIAN), atLeast(1)).getName();
           inOrder.verify(person.getAddress("the docks").getStreet(Locale.CHINESE)).getName();
         

         

        多少深存根在内部工作?

        
           //this:
           Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS);
           when(mock.getBar().getName(), "deep");
        
           //is equivalent of
           Foo foo = mock(Foo.class);
           Bar bar = mock(Bar.class);
           when(foo.getBar()).thenReturn(bar);
           when(bar.getName()).thenReturn("deep");
         

         

        当包含在链中的任何返回类型的方法不能被模拟时(例如:是原始类还是最终类),此功能将不起作用。这是因为java类型的系统。

      • CALLS_REAL_METHODS

        public static final  Answer < Object > CALLS_REAL_METHODS
        可选Answer用于mock(Class, Answer)

        Answer 可以用来定义未打开的调用的返回值。

        这个实现在处理遗留代码时会很有帮助。当使用这个实现时,未解压的方法将委托给真正的实现。这是创建一个默认调用真实方法的部分模拟对象的一种方法。

        像往常一样,您将阅读部分模拟警告:面向对象的编程通过将复杂性划分为单独的,特定的SRPy对象来解决更复杂的问题。部分模拟如何适应这种模式?那么,它只是不...部分模拟通常意味着复杂性已被移动到同一个对象上的不同方法。在大多数情况下,这不是您想要设计应用程序的方式。

        但是,有些情况下,部分模拟会变得很方便:处理不能轻易更改的代码(第三方接口,传统代码的临时重构等)。但是,我不会使用部分模拟来实现新的,测试驱动的,设计的代码。

        例:

        
         Foo mock = mock(Foo.class, CALLS_REAL_METHODS);
        
         // this calls the real implementation of Foo.getSomething()
         value = mock.getSomething();
        
         when(mock.getSomething()).thenReturn(fakeValue);
        
         // now fakeValue is returned
         value = mock.getSomething();
         
      • RETURNS_SELF

        public static final  Answer < Object > RETURNS_SELF
        可选Answer用于mock(Class, Answer)当一个方法被调用返回一个Type等于该类或一个超类的方法时,允许Builder mock返回自身。

        请记住,这个答案使用方法的返回类型。如果这个类型可以分配给模拟类,它将返回模拟。因此,如果你有一个方法返回一个超类(例如Object)它将匹配并返回模拟。

        考虑HttpRequesterWithHeaders中使用的HttpBuilder。
        
         public class HttpRequesterWithHeaders {
        
              private HttpBuilder builder;
        
              public HttpRequesterWithHeaders(HttpBuilder builder) {
                  this.builder = builder;
              }
        
              public String request(String uri) {
                  return builder.withUrl(uri)
                          .withHeader("Content-type: application/json")
                          .withHeader("Authorization: Bearer")
                          .request();
              }
          }
        
          private static class HttpBuilder {
        
              private String uri;
              private List<String> headers;
        
              public HttpBuilder() {
                  this.headers = new ArrayList<String>();
              }
        
               public HttpBuilder withUrl(String uri) {
                   this.uri = uri;
                   return this;
               }
        
               public HttpBuilder withHeader(String header) {
                   this.headers.add(header);
                   return this;
               }
        
               public String request() {
                  return uri + headers.toString();
               }
          }
         
        以下测试将成功
        
         @Test
          public void use_full_builder_with_terminating_method() {
              HttpBuilder builder = mock(HttpBuilder.class, RETURNS_SELF);
              HttpRequesterWithHeaders requester = new HttpRequesterWithHeaders(builder);
              String response = "StatusCode: 200";
        
              when(builder.request()).thenReturn(response);
        
              assertThat(requester.request("URI")).isEqualTo(response);
          }
         
    • 构造函数的细节

      • 的Mockito

        公众Mockito()
    • 方法细节

      • 嘲笑

        public static <T> T mock(Class <T> classToMock)
        创建给定的类或接口的模拟对象。

        见的例子中的javadoc Mockito

        参数:
        classToMock - 类或接口来模拟
        返回:
        模拟对象
      • 嘲笑

        public static <T> T mock(Class <T> classToMock,
                                  String  name)
        指定模拟名称。命名模拟可能对调试有帮助 - 名称用于所有验证错误。

        请注意,命名模拟不适用于使用太多模拟或协作者的复杂代码。 如果你有太多的mock,那么重构代码,这样很容易测试/调试,而不必命名模拟。

        如果你使用@Mock注释,那么你已经免费命名模拟! @Mock使用字段名称作为模拟名称。Read more.

        见的例子中的javadoc Mockito

        参数:
        classToMock - 类或接口来模拟
        name - 模拟
        返回:
        模拟对象
      • mockingDetails

        公共静态  MockingDetails  mockingDetails(Object  toInspect)
        返回一个MockingDetails实例,该实例可以检查特定对象的Mockito相关信息。可以用来找出给定的对象是否是Mockito模拟,或者找出给定的模拟是间谍还是模拟。

        在将来的Mockito版本中,MockingDetails可能会增长,并提供有关模拟的其他有用信息,例如调用,存根信息等。

        参数:
        toInspect - - 检查对象。空输入是允许的。
        返回:
        一个MockingDetails实例。
        以来:
        1.9.5
      • 嘲笑

        public static <T> T mock(Class <T> classToMock,
                                  Answer  defaultAnswer)
        创建一个指定的策略模拟其交互的答案。这是一个相当先进的功能,通常你不需要它来写出体面的测试。但是,使用旧系统时可能会有所帮助。

        这是默认的答案,所以只有当你不存在方法调用才会使用它

        
           Foo mock = mock(Foo.class, RETURNS_SMART_NULLS);
           Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
         

        见的例子中的javadoc Mockito

        参数:
        classToMock - 类或接口来模拟
        defaultAnswer - 未打开的方法的默认答案
        返回:
        模拟对象
      • 嘲笑

        public static <T> T mock(Class <T> classToMock,
                                  MockSettings  mockSettings)
        用一些非标准设置创建一个模拟。

        模拟的配置点数量增长,所以我们需要一个流利的方式来引入新的配置,而不会增加更多的重载Mockito.mock()方法。因此MockSettings

        
           Listener mock = mock(Listener.class, withSettings()
             .name("firstListner").defaultBehavior(RETURNS_SMART_NULLS));
           );
         
        小心使用,偶尔使用什么可能是你的测试需要非标准模拟的原因?被测试的代码是如此复杂以至于它需要非标准的模拟?你不喜欢重构测试中的代码,所以它是可测试的一个简单的方法?

        也可以看看 withSettings()

        见的例子中的javadoc Mockito

        参数:
        classToMock - 类或接口来模拟
        mockSettings - 额外的模拟设置
        返回:
        模拟对象
      • 间谍

        公共静态<T> T间谍(T对象)
        创建真实对象的间谍。间谍调用真正的方法,除非他们被扼杀。

        真正的间谍应该谨慎地偶尔使用,例如在处理遗留代码时。

        像往常一样,您将阅读部分模拟警告:面向对象编程通过将复杂性划分为单独的,特定的SRPy对象来解决复杂性问题。部分模拟如何适应这种模式?那么,它只是不...部分模拟通常意味着复杂性已被移动到同一个对象上的不同方法。在大多数情况下,这不是您想要设计应用程序的方式。

        但是,有些情况下,部分模拟会变得很方便:处理不能轻易更改的代码(第三方接口,传统代码的临时重构等)。但是,我不会使用部分模拟来实现新的,测试驱动的,设计的代码。

        例:

        
           List list = new LinkedList();
           List spy = spy(list);
        
           //optionally, you can stub out some methods:
           when(spy.size()).thenReturn(100);
        
           //using the spy calls real methods
           spy.add("one");
           spy.add("two");
        
           //prints "one" - the first element of a list
           System.out.println(spy.get(0));
        
           //size() method was stubbed - 100 is printed
           System.out.println(spy.size());
        
           //optionally, you can verify
           verify(spy).add("one");
           verify(spy).add("two");
         

        关于间谍真相的重要窍门!

        1. 有时使用when(Object)吝啬的间谍是不可能或不切实际的因此,对于间谍,建议始终使用doReturnAnswerThrow()CallRealMethod 存根方法的家庭。例:
          
             List list = new LinkedList();
             List spy = spy(list);
          
             //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
             when(spy.get(0)).thenReturn("foo");
          
             //You have to use doReturn() for stubbing
             doReturn("foo").when(spy).get(0);
           
        2. Mockito *不会将调用委托给传入的实例,而是实际创建一个副本。所以如果你保留真实的实例并与之交互,不要期望被侦察者知道这些交互以及它们对实际实例状态的影响。其必然结果是,当* unstubbed *方法被调用*在间谍*,但*不上真正的实例*,你不会看到真正的实例的任何影响。
        3. 留意最后的方法。Mockito不会嘲笑最后的方法,所以底线是:当你窥探真实的物体时,你试图存根最后的方法=麻烦。你也将无法验证这些方法。

        见的例子中的javadoc Mockito

        请注意,间谍不会有任何关于间谍类型的注释,因为CGLIB不会重写它们。对于依靠间谍来获得这些注释的代码来说,可能会很麻烦。

        参数:
        object - 监视
        返回:
        一个真正的对象的间谍
      • 间谍

        @Incubating 
        public static <T> T spy(Class <T> classToSpy)
        请参阅文档spy(Object)滥用间谍暗示代码设计的气味。

        这个方法与原来的方法相反spy(Object),是基于类而不是一个对象来创建一个间谍。有时候,基于类创建间谍更为方便,并避免提供一个间谍对象的实例。这对侦察抽象类非常有用,因为它们不能被实例化。另见MockSettings.useConstructor(Object...)

        例子:

        
           SomeAbstract spy = spy(SomeAbstract.class);
        
           //Robust API, via settings builder:
           OtherAbstract spy = mock(OtherAbstract.class, withSettings()
              .useConstructor().defaultAnswer(CALLS_REAL_METHODS));
        
           //Mocking a non-static inner abstract class:
           InnerAbstract spy = mock(InnerAbstract.class, withSettings()
              .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
         
        类型参数:
        T - 间谍的类型
        参数:
        classToSpy - 要窥探的班级
        返回:
        提供的类的间谍
        以来:
        1.10.12
      • 什么时候

        public static <T>  OngoingStubbing <T> when(T methodCall)
        启用存根方法。当你想要模拟特定的方法被调用时返回特定的值使用它。

        简单地说:“  x方法被调用,然后返回y”。

        例子:

        
         when(mock.someMethod()).thenReturn(10);
        
         //you can use flexible argument matchers, e.g:
         when(mock.someMethod(anyString())).thenReturn(10);
        
         //setting exception to be thrown:
         when(mock.someMethod("some arg")).thenThrow(new RuntimeException());
        
         //you can set different behavior for consecutive method calls.
         //Last stubbing (e.g: thenReturn("foo")) determines the behavior of further consecutive calls.
         when(mock.someMethod("some arg"))
          .thenThrow(new RuntimeException())
          .thenReturn("foo");
        
         //Alternative, shorter version for consecutive stubbing:
         when(mock.someMethod("some arg"))
          .thenReturn("one", "two");
         //is the same as:
         when(mock.someMethod("some arg"))
          .thenReturn("one")
          .thenReturn("two");
        
         //shorter version for consecutive method calls throwing exceptions:
         when(mock.someMethod("some arg"))
          .thenThrow(new RuntimeException(), new NullPointerException();
        
         
        有关throwables的void方法,请参见: doThrow(Throwable...)

        可以覆盖桩号:例如,普通桩可以进入夹具设置,但测试方法可以覆盖它。请注意,覆盖残片是一种潜在的代码异味,指出了太多的残片。

        一旦被存根,该方法将总是返回存根值,而不管被调用的次数多少。

        最后的茬更重要 - 当你多次用相同的参数扼杀相同的方法。

        尽管可以验证存根调用,但通常这只是多余的比方说,你已经残废了foo.bar()如果你的代码关心什么foo.bar()返回,那么别的东西就会中断(通常在verify()执行之前)。如果你的代码不在乎什么get(0)返回,那么它不应该被扼杀。不服气?看到这里

        见的例子中的javadoc Mockito

        参数:
        methodCall - 方法被扼杀
        返回:
        OngoingStubbing对象用于流利地存根。 不要创建对此返回对象的引用。
      • 校验

        public static <T> T verify(T mock)
        验证一次发生的某些行为

        别名verify(mock, times(1))如:

        
           verify(mock).someMethod("some arg");
         
        以上相当于:
        
           verify(mock, times(1)).someMethod("some arg");
         

        使用equals()方法比较传递的参数阅读ArgumentCaptorArgumentMatcher找出其他方式匹配/断言传递的参数。

        尽管可以验证存根调用,但通常这只是多余的比方说,你已经残废了foo.bar()如果你的代码关心什么foo.bar()返回,那么别的东西就会中断(通常在verify()执行之前)。如果你的代码不在乎什么get(0)返回,那么它不应该被扼杀。不服气?看到这里

        见的例子中的javadoc Mockito

        参数:
        mock - 待验证
        返回:
        模拟对象本身
      • 校验

        public static <T> T验证(T模拟,
                                    VerificationMode  模式)
        验证某些行为发生至少一次/确切的次数/从不。例如:
        
           verify(mock, times(5)).someMethod("was called five times");
        
           verify(mock, atLeast(2)).someMethod("was called at least two times");
        
           //you can use flexible argument matchers, e.g:
           verify(mock, atLeastOnce()).someMethod(anyString());
         
        次(1)是默认值,可以省略

        使用equals()方法比较传递的参数阅读ArgumentCaptorArgumentMatcher找出其他方式匹配/断言传递的参数。

         

        参数:
        mock - 待验证
        mode - times(x),atLeastOnce()或never()
        返回:
        模拟对象本身
      • 重启

        public static <T> void reset(T ... mocks)
        智能Mockito用户很难使用这个功能,因为他们知道这可能是一个糟糕的测试的迹象。通常情况下,你不需要重置你的模拟,只是为每个测试方法创建新的模拟。

        不要#reset()考虑写一些简单,小而重点明确的测试方法,而不要考虑冗长的,过度规定的测试。 第一个潜在的代码气味正reset()处于测试方法的中间。这可能意味着你测试太多了。按照你的测试方法的低语:“请保持我们的小而专注于单一的行为”。在mockito邮件列表上有几个线程。

        我们添加reset()方法的唯一原因是使用容器注入的模拟工作成为可能。欲了解更多信息,请参阅常见问题(这里)。

        不要伤害你自己 reset()在测试方法的中间是一个代码气味(你可能测试太多)。

        
           List mock = mock(List.class);
           when(mock.size()).thenReturn(10);
           mock.add(1);
        
           reset(mock);
           //at this point the mock forgot any interactions & stubbing
         
        类型参数:
        T - 嘲笑的类型
        参数:
        mocks - 重置
      • clearInvocations

        public static <T> void clearInvocations(T ... mocks)
        使用这个方法只是为了清除调用,当存根是非平凡的。用例可以是:
        • 你正在使用依赖注入框架来注入你的模拟。
        • 这个模拟是在有状态的情况下使用的。例如,一个类是独立的,这取决于你的模拟。
        尽量避免这种方法,不惜一切代价。只有清除调用,如果你不能有效地测试你的程序。
        类型参数:
        T - 嘲笑的类型
        参数:
        mocks - 嘲笑清除调用
      • verifyNoMoreInteractions

        公共静态无效verifyNoMoreInteractions(对象 ...嘲笑)
        检查是否有任何给定的模拟有任何未经验证的交互。

        你可以在验证你的模拟之后使用这个方法 - 确保你的模拟中没有其他的东西被调用。

        另请参阅never()- 它更加明确,并充分传达意图。

        存根调用(如果调用)也被视为交互。

        一句警告:谁做了很多经典的一些用户,期望-运行-验证嘲讽倾向于使用verifyNoMoreInteractions()非常频繁,甚至在每个测试方法。 verifyNoMoreInteractions()不建议在每个测试方法中使用。verifyNoMoreInteractions()是交互测试工具包的一个方便的断言。只有在相关时才使用它。滥用它会导致过度指定,不易维护的测试。你可以在这里找到更多的阅读 

        此方法还将检测在测试方法之前发生的未经验证的调用,例如:in setUp()@Beforemethod或构造函数中。考虑编写漂亮的代码,只在测试方法中进行交互。

        例:

        
         //interactions
         mock.doSomething();
         mock.doSomethingUnexpected();
        
         //verification
         verify(mock).doSomething();
        
         //following will fail because 'doSomethingUnexpected()' is unexpected
         verifyNoMoreInteractions(mock);
        
         
        见的例子中的javadoc Mockito
        参数:
        mocks - 待验证
      • verifyZeroInteractions

        公共静态无效verifyZeroInteractions(对象 ...嘲笑)
        验证除了先前验证的交互之外,在给定的模拟上没有发生交互。
        这种方法具有相同的行为verifyNoMoreInteractions(Object...)
        参数:
        mocks - 待验证
      • doThrow

        公共静态  Stubber  doThrow(Throwable ... toBeThrown)
        使用doThrow()时要与存根异常的无效方法。

        when(Object)由于编译器不喜欢方括号内的void方法 ,所以 需要使用不同的方法

        例:

        
           doThrow(new RuntimeException()).when(mock).someVoidMethod();
         
        参数:
        toBeThrown - 当被调用的方法被调用时被抛出
        返回:
        stubber - 选择一个存根的方法
      • doThrow

        公共静态  Stubber  doThrow(Class <?extends Throwable > toBeThrown)
        使用doThrow()时要与存根异常的无效方法。

        将为每个方法调用创建一个新的异常实例。

        when(Object)由于编译器不喜欢方括号内的void方法 ,所以 需要使用不同的方法

        例:

        
           doThrow(RuntimeException.class).when(mock).someVoidMethod();
         
        参数:
        toBeThrown - 当被调用的方法被调用时被抛出
        返回:
        stubber - 选择一个存根的方法
        以来:
        2.1.0
      • doThrow

        public static  Stubber  doThrow(Class <?extends Throwable > toBeThrown,
                                       Class <?extends Throwable > ... toBeThrownNext)
        doThrow(Class)设置连续的异常类相同记住要使用 doThrow()时要存根的void方法抛出指定类的几个异常。

        将为每个方法调用创建一个新的异常实例。

        when(Object)由于编译器不喜欢方括号内的void方法 ,所以 需要使用不同的方法

        例:

        
           doThrow(RuntimeException.class, BigFailure.class).when(mock).someVoidMethod();
         
        参数:
        toBeThrown - 当被调用的方法被调用时被抛出
        toBeThrownNext - 当被调用的方法被调用时接下来被抛出
        返回:
        stubber - 选择一个存根的方法
        以来:
        2.1.0
      • doCallRealMethod

        public static  Stubber  doCallRealMethod()
        使用doCallRealMethod()时要调用真正执行的方法。

        像往常一样,您将阅读部分模拟警告:面向对象的编程通过将复杂性划分为单独的,特定的SRPy对象来解决更复杂的问题。部分模拟如何适应这种模式?那么,它只是不...部分模拟通常意味着复杂性已被移动到同一个对象上的不同方法。在大多数情况下,这不是您想要设计应用程序的方式。

        但是,有些情况下,部分模拟会变得很方便:处理不能轻易更改的代码(第三方接口,传统代码的临时重构等)。但是,我不会使用部分模拟来实现新的,测试驱动的,设计的代码。

        另请参阅javadoc spy(Object)以了解有关部分嘲讽的更多信息。 Mockito.spy()是创建部分模拟的推荐方法。 原因是它保证真正的方法被称为正确构造的对象,因为你负责构造传递给spy()方法的对象。

        例:

        
           Foo mock = mock(Foo.class);
           doCallRealMethod().when(mock).someVoidMethod();
        
           // this will call the real implementation of Foo.someVoidMethod()
           mock.someVoidMethod();
         

        见的例子中的javadoc Mockito

        返回:
        stubber - 选择一个存根的方法
        以来:
        1.9.5
      • doAnswer

        公共静态  Stubber  doAnswer(回答  )
        使用doAnswer()时要与存根通用空隙的方法Answer

        when(Object)由于编译器不喜欢方括号内的void方法 ,所以 需要使用不同的方法

        例:

        
          doAnswer(new Answer() {
              public Object answer(InvocationOnMock invocation) {
                  Object[] args = invocation.getArguments();
                  Mock mock = invocation.getMock();
                  return null;
              }})
          .when(mock).someMethod();
         

        见的例子中的javadoc Mockito

        参数:
        answer - 在调用存根方法时回答
        返回:
        stubber - 选择一个存根的方法
      • 没做什么

        公共静态  Stubber  doNothing()
        使用doNothing()设置无效的方法什么也不做。请注意,虚拟方法嘲笑默认情况下不做任何事情! 但是,在doNothing()方便的情况下,

         

        1. 连续调用一个void方法:
          
             doNothing().
             doThrow(new RuntimeException())
             .when(mock).someVoidMethod();
          
             //does nothing the first time:
             mock.someVoidMethod();
          
             //throws RuntimeException the next time:
             mock.someVoidMethod();
           
        2. 当你窥探真实的物体时,你想让void方法什么也不做:
          
             List list = new LinkedList();
             List spy = spy(list);
          
             //let's make clear() do nothing
             doNothing().when(spy).clear();
          
             spy.add("one");
          
             //clear() does nothing, so the list still contains "one"
             spy.clear();
           

        见的例子中的javadoc Mockito

        返回:
        stubber - 选择一个存根的方法
      • doReturn

        公共静态  Stubber  doReturn(Object  toBeReturned)
        使用doReturn()在那些极少数情况下,你不能使用when(Object)

        注意when(Object)总是建议用于存根,因为它是参数类型安全的,并且更具可读性(特别是在连续调用存根时)。

        以下是doReturn()方便使用的情况:

         

        1. 当间谍侦察真实的对象和调用真正的方法间谍带来的副作用
          
             List list = new LinkedList();
             List spy = spy(list);
          
             //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
             when(spy.get(0)).thenReturn("foo");
          
             //You have to use doReturn() for stubbing:
             doReturn("foo").when(spy).get(0);
           
        2. 覆盖以前的例外情况:
          
             when(mock.foo()).thenThrow(new RuntimeException());
          
             //Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown.
             when(mock.foo()).thenReturn("bar");
          
             //You have to use doReturn() for stubbing:
             doReturn("bar").when(mock).foo();
           
        以上场景展示了Mockito优雅语法的折衷。请注意,情景是非常罕见的,虽然。间谍应该是零星的,压倒一切的例外情况非常罕见。更不用说,一般来说,被覆盖的残片是一种潜在的代码味道,指出了太多的残片。

        见的例子中的javadoc Mockito

        参数:
        toBeReturned - 当被调用的方法被调用时被返回
        返回:
        stubber - 选择一个存根的方法
      • doReturn

        公共静态  Stubber  doReturn(Object  toBeReturned,
                                        Object ... toBeReturnedNext)
        相同doReturn(Object)但设置要返回的连续值。请记住doReturn()在不能使用的情况下使用 这些罕见的场合when(Object)

        注意when(Object)总是建议用于存根,因为它是参数类型安全的,并且更具可读性(特别是在连续调用存根时)。

        以下是doReturn()方便使用的情况:

         

        1. 当间谍侦察真实的对象和调用真正的方法间谍带来的副作用
          
             List list = new LinkedList();
             List spy = spy(list);
          
             //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
             when(spy.get(0)).thenReturn("foo", "bar", "qix");
          
             //You have to use doReturn() for stubbing:
             doReturn("foo", "bar", "qix").when(spy).get(0);
           
        2. 覆盖以前的例外情况:
          
             when(mock.foo()).thenThrow(new RuntimeException());
          
             //Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown.
             when(mock.foo()).thenReturn("bar", "foo", "qix");
          
             //You have to use doReturn() for stubbing:
             doReturn("bar", "foo", "qix").when(mock).foo();
           
        以上场景展示了Mockito优雅语法的折衷。请注意,情景是非常罕见的,虽然。间谍应该是零星的,压倒一切的例外情况非常罕见。更不用说,一般来说,被覆盖的残片是一种潜在的代码味道,指出了太多的残片。

        见的例子中的javadoc Mockito

        参数:
        toBeReturned - 当被调用的方法被调用时被返回
        toBeReturnedNext - 在调用存根方法时连续调用返回
        返回:
        stubber - 选择一个存根的方法
        以来:
        2.1.0
      • 为了

        公共静态  InOrder inOrder  (Object ... mocks)
        创建InOrder允许按顺序验证模拟的对象。
        
           InOrder inOrder = inOrder(firstMock, secondMock);
        
           inOrder.verify(firstMock).add("was called first");
           inOrder.verify(secondMock).add("was called second");
         
        按顺序进行验证是非常灵活的 - 您不必逐个验证所有交互,需要验证您有兴趣测试的所有交互

        此外,您可以创建InOrder对象,只传递与按序验证相关的模拟。

        InOrder验证是“贪婪”的,但你几乎不会注意到它。如果你想了解更多,请阅读 这个维基页面

        从Mockito 1.8.4开始,您可以按顺序验证NoMoreInvocations()。阅读更多:InOrder.verifyNoMoreInteractions()

        见的例子中的javadoc Mockito

        参数:
        mocks - 按顺序核实
        返回:
        InOrder对象用于按顺序进行验证
      • ignoreStubs

        public static  Object [] ignoreStubs(Object ... mocks)
        为了验证,忽略了给定模拟的残留方法。有时加上verifyNoMoreInteractions()或验证时有用inOrder()有助于避免冗余验证,通常我们对验证存根不感兴趣。

        警告ignoreStubs()可能会导致过度使用verifyNoMoreInteractions(ignoreStubs(...)); Bear记住,Mockito不建议verifyNoMoreInteractions() 按照javadoc中概述的原因轰击每个测试verifyNoMoreInteractions(Object...) 其他的话:所有* stubbed *方法的给定mock被标记*验证*,以便他们不进入verifyNoMoreInteractions()期间的一种方法。

        这种方法改变输入模拟这个方法只是为了方便返回输入模拟。

        包括在内的被忽略的存根也将被忽略用于验证InOrder.verifyNoMoreInteractions()看第二个例子。

        例:

        
          //mocking lists for the sake of the example (if you mock List in real you will burn in hell)
          List mock1 = mock(List.class), mock2 = mock(List.class);
        
          //stubbing mocks:
          when(mock1.get(0)).thenReturn(10);
          when(mock2.get(0)).thenReturn(20);
        
          //using mocks by calling stubbed get(0) methods:
          System.out.println(mock1.get(0)); //prints 10
          System.out.println(mock2.get(0)); //prints 20
        
          //using mocks by calling clear() methods:
          mock1.clear();
          mock2.clear();
        
          //verification:
          verify(mock1).clear();
          verify(mock2).clear();
        
          //verifyNoMoreInteractions() fails because get() methods were not accounted for.
          try { verifyNoMoreInteractions(mock1, mock2); } catch (NoInteractionsWanted e);
        
          //However, if we ignore stubbed methods then we can verifyNoMoreInteractions()
          verifyNoMoreInteractions(ignoreStubs(mock1, mock2));
        
          //Remember that ignoreStubs() *changes* the input mocks and returns them for convenience.
         
        忽略存根可用于验证顺序
        
          List list = mock(List.class);
          when(mock.get(0)).thenReturn("foo");
        
          list.add(0);
          System.out.println(list.get(0)); //we don't want to verify this
          list.clear();
        
          InOrder inOrder = inOrder(ignoreStubs(list));
          inOrder.verify(list).add(0);
          inOrder.verify(list).clear();
          inOrder.verifyNoMoreInteractions();
         
        参数:
        mocks - 输入模拟将被改变
        返回:
        同样的模拟参数传入
        以来:
        1.9.0
      • public static  VerificationMode  times(int wantedNumberOfInvocations)
        允许验证确切的调用次数。例如:
        
           verify(mock, times(2)).someMethod("some arg");
         
        见的例子中的javadoc Mockito
        参数:
        wantedNumberOfInvocations - 想要的调用次数
        返回:
        验证模式
      • 至少一次

        公共静态  验证模式  atLeastOnce()
        允许至少一次验证。例如:
        
           verify(mock, atLeastOnce()).someMethod("some arg");
         
        别名atLeast(1)

        见的例子中的javadoc Mockito

        返回:
        验证模式
      • 至少

        公共静态  VerificationMode  atLeast(int minNumberOfInvocations)
        允许至少x验证。例如:
        
           verify(mock, atLeast(3)).someMethod("some arg");
         
        见的例子中的javadoc Mockito
        参数:
        minNumberOfInvocations - 最少的调用次数
        返回:
        验证模式
      • 最多

        公共静态  VerificationMode  atMost(int maxNumberOfInvocations)
        允许进行最多x验证。例如:
        
           verify(mock, atMost(3)).someMethod("some arg");
         
        见的例子中的javadoc Mockito
        参数:
        maxNumberOfInvocations - 最大的调用次数
        返回:
        验证模式
      • 电话

        公共静态  VerificationMode  调用(int wantedNumberOfInvocations)
        按顺序进行非贪婪验证。例如
        
           inOrder.verify( mock, calls( 2 )).someMethod( "some arg" );
         
        • 如果方法被调用3次不会失败,不像时间(2)
        • 不会将第三次调用标记为已验证,不像atLeast(2)
        该验证模式只能用于验证。
        参数:
        wantedNumberOfInvocations - 要验证的调用次数
        返回:
        验证模式
      • 只要

        public static  VerificationMode  only()
        允许检查给定的方法是唯一被调用的方法。例如:
        
           verify(mock, only()).someMethod();
           //above is a shorthand for following 2 lines of code:
           verify(mock).someMethod();
           verifyNoMoreInvocations(mock);
         

        也可以看看 verifyNoMoreInteractions(Object...)

        见的例子中的javadoc Mockito

        返回:
        验证模式
      • 时间到

        公共静态  VerificationWithTimeout  超时(长毫秒)
        允许超时验证。它会导致验证等待指定的时间段进行期望的交互,而不是立即失败,如果还没有发生。可能对并发条件下的测试有用。

        这不同于after()在()之后将等待整个周期,除非最后的测试结果是早期知道的(例如,如果一个never()失败),而timeout()将在验证通过后尽早停止,当使用时产生不同的行为与时间(2),例如,可以通过,然后失败。在这种情况下,超时将在时间(2)通过后立即传递,而在时间(2)失败后运行,然后失败。

        这个功能应该很少使用 - 找出测试你的多线程系统的更好方法。

        
           //passes when someMethod() is called within given time span
           verify(mock, timeout(100)).someMethod();
           //above is an alias to:
           verify(mock, timeout(100).times(1)).someMethod();
        
           //passes as soon as someMethod() has been called 2 times before the given timeout
           verify(mock, timeout(100).times(2)).someMethod();
        
           //equivalent: this also passes as soon as someMethod() has been called 2 times before the given timeout
           verify(mock, timeout(100).atLeast(2)).someMethod();
        
           //verifies someMethod() within given time span using given verification mode
           //useful only if you have your own custom verification modes.
           verify(mock, new Timeout(100, yourOwnVerificationMode)).someMethod();
         
        见的例子中的javadoc Mockito
        参数:
        millis - - 以毫秒为单位的时间跨度
        返回:
        验证模式
      •  (long millis)之后的公共静态  VerificationAfterDelay
        允许在给定的时间内进行验证。它会导致验证等待指定的时间段进行所需的交互,而不是立即失败(如果尚未发生)。可能对并发条件下的测试有用。

        这不同于timeout()在()之后等待整个周期,而timeout()将在验证通过后立即提前停止,在与时间(2)一起使用时产生不同的行为,例如,可以通过然后失败。在这种情况下,超时会在时间(2)通过后立即传递,而在之后的时间将运行整个时间,哪个时间点将失败,因为时间(2)失败。

        这个功能应该很少使用 - 找出测试你的多线程系统的更好方法。

        尚未实施以使用InOrder验证。

        
           //passes after 100ms, if someMethod() has only been called once at that time.
           verify(mock, after(100)).someMethod();
           //above is an alias to:
           verify(mock, after(100).times(1)).someMethod();
        
           //passes if someMethod() is called *exactly* 2 times after the given timespan
           verify(mock, after(100).times(2)).someMethod();
        
           //passes if someMethod() has not been called after the given timespan
           verify(mock, after(100).never()).someMethod();
        
           //verifies someMethod() after a given time span using given verification mode
           //useful only if you have your own custom verification modes.
           verify(mock, new After(100, yourOwnVerificationMode)).someMethod();
         
        见的例子中的javadoc Mockito
        参数:
        millis - - 以毫秒为单位的时间跨度
        返回:
        验证模式
      • validateMockitoUsage

        公共静态无效validateMockitoUsage()
        首先,如果遇到任何问题,我建议您阅读Mockito FAQ:https//github.com/mockito/mockito/wiki/FAQ

        如有疑问,您也可以发送到mockito邮件列表:http//groups.google.com/group/mockito

        validateMockitoUsage() 明确验证框架状态以检测Mockito的无效使用。不过,这个功能是可选的,因为Mockito始终验证使用情况...但是有一个小问题需要阅读。

        错误使用的例子:

        
         //Oops, thenReturn() part is missing:
         when(mock.get());
        
         //Oops, verified method call is inside verify() where it should be on the outside:
         verify(mock.execute());
        
         //Oops, missing method to verify:
         verify(mock);
         
        如果你滥用Mockito会抛出异常,这样你就知道你的测试是否写得正确。问题是Mockito 在下一次使用框架时会进行验证(例如,下一次验证,存根,调用模拟等)。但是,即使在下一次测试中可能会抛出异常,异常消息中也会包含一个带有缺陷位置的可导航堆栈跟踪元素因此,您可以点击并找到Mockito被滥用的地方。

        有时候,你可能想明确地验证框架的用法。例如,其中一个用户想要投入validateMockitoUsage()他的@After方法,以便他在误用Mockito时立即知道。没有它,他会早在下一次他就使用这个框架就知道了validateMockitoUsage()进入的另外一个好处@After是,jUnit跑步者和规则在测试方法中总会失败,而普通的“下一次”验证可能会使下一个测试方法失败但即使JUnit可能会将下一个测试报告为红色,也不要担心,只需单击异常消息中的可导航堆栈跟踪元素即可找到您误用mockito的地方。

        内置runner MockitoJUnitRunner和规则:MockitoRule在每个测试方法之后,执行validateMockitoUsage()。

        请记住,通常情况下,您不必validateMockitoUsage() 在下一次触发框架验证时就足够了,这主要是因为增强了异常消息和可点击的缺陷位置。但是,如果您已经拥有足够的测试基础架构(比如您自己的所有测试的运行者或基类),那么我会推荐使用validateMockitoUsage(),因为添加了一个特殊的操作来实现@After零成本。

        见的例子中的javadoc Mockito

      • withSettings

        public static  MockSettings  withSettings()
        允许使用附加的模拟设置进行模拟创建。

        不要经常使用它。考虑编写使用简单模拟的简单测试。重复我之后:简单的测试推简单,KISSy,可读和可维护的代码。如果你不能以简单的方式编写测试 - 重构测试中的代码。

        模拟设置的例子:

        
           //Creates mock with different default answer & name
           Foo mock = mock(Foo.class, withSettings()
               .defaultAnswer(RETURNS_SMART_NULLS)
               .name("cool mockie"));
        
           //Creates mock with different default answer, descriptive name and extra interfaces
           Foo mock = mock(Foo.class, withSettings()
               .defaultAnswer(RETURNS_SMART_NULLS)
               .name("cool mockie")
               .extraInterfaces(Bar.class));
         
        MockSettings已经出现了两个原因。首先,当需求到来时,很容易添加另一个模拟设置。其次,为了能够结合不同的模拟设置而不需要引入大量的重载模拟()方法。

        查看javadoc MockSettings了解可能的模拟设置。

         

        返回:
        模拟设置实例与默认值。
      • 描述

        public static  VerificationMode  description(String  description)
        如果验证失败,则添加要打印的说明。
        
         verify(mock, description("This will print on failure")).someMethod("some arg");
         
        参数:
        description - 描述打印失败。
        返回:
        验证模式
        以来:
        2.1.0
      • mockitoSession

        @Incubating 
        public static  MockitoSessionBuilder  mockitoSession()
        MockitoSession 是一个可选的强烈推荐的功能,通过消除样板代码和添加额外的验证来帮助推动清洁测试。
posted @ 2017-11-23 09:55  小学生II  阅读(1107)  评论(0编辑  收藏  举报