mock对象一旦被创建,会记住所有的验证,并在你感兴趣的时候提供可选的校验
来谈谈stubbing吧 //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则返回0,boolean则返回falsestubbing 可以被重写:例如常见的stub可以去固定设置,但测试方法可以覆盖它。请注意,overridding存根是一个潜在的代码味道,指太多的存根一旦创建了stubbing,不论调用多少次测试方法都会返回一个值 //重复stub两次,则以第二次为准。如下将返回”second”: when(mockedList.get(0)).thenReturn(“first”).thenReturn(“second”); 但是,如果实际调用的次数超过了stub过的次数,则会一直返回最后一次stub的值。 参数匹配 //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(someString -> someString.length() > 5); 如果想要传入某种类型的值都返回一种结果,需要怎么做呢?stubbing 使用了内置的anyint() matcher.除了anyint()还有其他类型的matcher,但是有个延迟是,如果调用方法需要传入多个参数,其中一个使用了参数matcher,那么所有的参数都需要使用matcher有时候我们的许多类型都不是内建的一些类型,我们需要自己写一个类或者特殊对象,这个时候就需要自己定义matcher了 调用次数的校验 //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("five times"); verify(mockedList, atMost(5)).add("three times"); 调用方法时抛出异常doThrow(new RuntimeException()).when(mockedList).clear();
后面还会再介绍几个类似的方法,例如doReturn()。
验证方法调用顺序//下面的代码验证firstMock先被调用,secondMock后被调用。
inOrder.verify(firstMock).add(“was called first”);
inOrder.verify(secondMock).add(“was called second”);
先写到这里吧,等下班了再整理下一篇
