//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);
参数匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//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));
//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");
// 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");
when(mock.someMethod(anyString())).thenAnswer( new Answer() { public Object answer(InvocationOnMock invocation){ Object[] args = invocation.getArguments(); Object mock = invocation.getMock(); return"called with arguments: " + Arrays.toString(args); } });
//Following prints "called with arguments: [foo]" System.out.println(mock.someMethod("foo"));
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);
参数捕捉
1 2 3 4 5
//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);
序列化的mock
1
List serializableMock = mock(List.class, withSettings().serializable());
验证超时
1 2 3 4 5 6 7 8 9 10 11 12
//passes when someMethod() is called no later than within 100 ms //exits immediately when verification is satisfied (e.g. may not wait full 100 ms) 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 under 100 ms verify(mock, timeout(100).times(2)).someMethod();
//equivalent: this also passes as soon as someMethod() has been called 2 times under 100 ms verify(mock, timeout(100).atLeast(2)).someMethod();
mock抽象类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//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 function = spy(Function.class);
//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));
// 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();
Java8匹配器支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// 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(){ publicbooleanmatches(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))).thenReturn(null);
Java8 Answer接口支持
1 2 3 4 5 6 7 8 9
// 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());
对final对象,方法,枚举的支持
1 2 3 4 5 6 7 8 9 10
finalclassFinalClass{ final String finalMethod(){ return"something"; } }
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());
对spy对象要慎用when/thenReturn
1 2 3 4 5 6 7 8 9 10
//optionally, you can verify verify(spy).add("one"); verify(spy).add("two"); //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);