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开发人员随时随地记录他们编写的代码,天天都提交。html

    内容

    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节java

    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(); 

    一旦建立,模拟将记住全部的交互。而后,您能够选择性地验证您感兴趣的任何互动。android

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

    //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 heregit

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

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

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

    参数匹配器警告:编程

    若是使用参数匹配器,全部参数都必须由匹配器提供。json

    如下示例显示验证,但一样适用于存根:api

    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中,基于类型化界面的这些自定义答案也能够减小样板。特别是,这种方法将使测试使用回调函数更容易。方法 answer answerVoid  可用于建立答案。他们依赖于相关的答案接口, 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; 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  是一个可选的强烈推荐的功能,经过消除样板代码和添加额外的验证来帮助推进清洁测试。
相关文章
相关标签/搜索