Introduction to Mockito (based on 3.11.1)

Mockito features include mock object creation, validation interaction, and stub method invocation.

Noun explanation:

  • Stub: stub. The process of configuring what results a mock object should return when one of its methods is called.
  • Interaction: a call to a method occurs.
  • I don’t spy on you.

Verify interaction:

import static org.mockito.Mockito.*;

// Create a mock object
List mockedList = mock(List.class);

// Use a mock object - it does not throw any "unexpected interaction" exceptions
mockedList.add("one");
mockedList.clear();

// Optional, unambiguous, readable validation
verify(mockedList).add("one");
verify(mockedList).clear();
Copy the code

Stub method call:

// You can mock specific classes, not just mock interfaces
LinkedList mockedList = mock(LinkedList.class);

// Stub before the actual call
when(mockedList.get(0)).thenReturn("first");

// This will print "first"
System.out.println(mockedList.get(0));

// "null" will be printed here because the get(999) method is not stubbed
System.out.println(mockedList.get(999));
Copy the code

More:

  • mock()/@Mock: Creates mock objects
    • (Optional) Specific behavior can be specified through Answer/MockSettings
    • When ()/given() specifies the behavior that the mock object should have
    • If the mock object doesn’t provide the results you need, you can extend it yourself by inheriting the Answer interface.
  • Spy ()/ @spy: Partial mock, where real methods are called but can still be verified and stubbed.
  • @InjectMocksThat will be@Spy@MockMocks/Spies objects that automatically inject related fields.
  • verify(): checks whether the method was called with the given argument
    • You can use flexible parameter matching, such as any() to represent any expression
    • Or use @captor to capture the arguments of the call
  • Use BDDMockito to try a behavior-driven development syntax
  • Use Mockito on Android thanks to the Dexmaker team for their work

Remember:

  • Don’t mock out of your type
  • Do not mock value objects
  • Don’t mock everything
  • Show your love in the quiz!

Click here for more documentation and examples. All of the documentation is generated using JavaDoc so you don’t need to look it up very often. There’s also a RefCard.

If you have suggestions, documentation lookup is not clear, or find bugs, please write to our mailing list. You can report feature requests and errors in GitHub.

Mockito document

The Mockito library allows you to create mock objects, validate method calls, and stub method calls.

1. Verify the mock object’s behavior (whether the method is called and the value returned from the call)

 // Let's statically import Mockito to make our code look cleaner
 import static org.mockito.Mockito.*;

 // Create a mock object
 List mockedList = mock(List.class);

 // Use mock objects
 mockedList.add("one");
 mockedList.clear();

 / / verification
 verify(mockedList).add("one");
 verify(mockedList).clear();
Copy the code

2. Add stubs: Specify the return value of the mock object method call

 // You can mock concrete classes, not just interfaces
 LinkedList mockedList = mock(LinkedList.class);

 // Add the stub
 when(mockedList.get(0)).thenReturn("first");
 when(mockedList.get(1)).thenThrow(new RuntimeException());

 / / output "first"
 System.out.println(mockedList.get(0));

 Throw a runtime exception
 System.out.println(mockedList.get(1));

 // print "null" because get(999) is not stubbed
 System.out.println(mockedList.get(999));

 // While it is possible to validate stub method calls, it is usually redundant.
 // If your code cares about the return value of get(0), something is broken (usually before calling verify()).
 // If your code does not care about the return value of get(0), it should not be stubbed.
 verify(mockedList).get(0);

Copy the code
  • By default, a mock will return NULL, raw/original wrapper value, or an empty set for all method return values, depending on the case. For example, int/Integer returns 0 and Boolean/Boolean returns false.
  • The stub can be overwritten: for example, a normal stub can be set when entering the test fixture (before method), but it can be overwritten in the test method. Note that overwriting stubs is a potential code odor that indicates too many stubs.
  • Once stubbed, the method will always return a stub value, no matter how many times it is called.
  • The last stub is more important – when you stub the same method with the same argument multiple times. In other words: the order of stubs is ** important, ** but it is only rarely meaningful, such as when stubs are exactly the same method calls or when parameter matchers are used.

3. Match parameters

Mockito validates parameter values in the natural Java style. That is, by using equals(). Sometimes, when extra flexibility is needed, you can use the parameter matcher:

 // Use the built-in anyInt() argument matcher to create stubs
 when(mockedList.get(anyInt())).thenReturn("element");

 // Use a custom parameter matcher isValid()
 when(mockedList.contains(argThat(isValid()))).thenReturn(true);

 / / output "element"
 System.out.println(mockedList.get(999));

 // You can also use the parameter matcher for validation
 verify(mockedList).get(anyInt());

 // Parameter matchers can also be written in the Java 8 Lambdas style
 verify(mockedList).add(argThat(someString -> someString.length() > 5));
Copy the code

Parameter matchers allow flexible validation or stubs. See more examples of built-in matchers and custom parameter matchers/Hamcrest matchers. Click here or here.

For information about only ** custom argument matchers, ** see the Javadoc of the ArgumentMatcher class.

Use complex parameter matching wisely. The natural matching style of using equals() with anyX() matchers occasionally tends to provide clean and simple tests. Sometimes it’s best to refactor your code to allow equals() to match or even implement the equals() method to help with testing.

Also, read Section 15 or Javadoc for ArgumentCaptor classes. ArgumentCaptor is a special implementation of an argument matcher that captures argument values for further assertions.

Parameter matcher warning:

If you use a parameter matcher, all parameters must be supplied by the matcher.

The following example shows the use of a parameter matcher for validation, but it also works for stub method calls:

   verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
   Eq () is also a parameter matcher

   verify(mock).someMethod(anyInt(), anyString(), "third argument");
   // The above is written incorrectly - the exception is thrown because the third argument is not in the form of an argument matcher
Copy the code

Matcher methods such as anyObject() and eq() do not return matchers. Internally, they record a matcher on the stack and return a dummy value (usually empty). This implementation is due to static type safety imposed by the Java compiler. The result is that you cannot use anyObject(),eq() methods outside of validation/stubs.

4. Verify the exact number of calls/at least x calls/never calls

 // Use mock objects
 mockedList.add("once");

 mockedList.add("twice");
 mockedList.add("twice");

 mockedList.add("three times");
 mockedList.add("three times");
 mockedList.add("three times");

 The following two validations have the same effect - times(1) is used by default
 verify(mockedList).add("once");
 verify(mockedList, times(1)).add("once");

 // Verify the exact number of calls
 verify(mockedList, times(2)).add("twice");
 verify(mockedList, times(3)).add("three times");

 // Validate with never(). Never () is an alias for times(0)
 verify(mockedList, never()).add("never happened");

 // Use atLeast()/atMost() validation
 verify(mockedList, atMostOnce()).add("once");
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("three times");
 verify(mockedList, atMost(5)).add("three times");
Copy the code

**times(1) is the default. ** The explicit use of times(1) can therefore be omitted.

5. Stub has abnormal void method

   doThrow(new RuntimeException()).when(mockedList).clear();

   // The following code throws an exception
   mockedList.clear();
Copy the code

In verse 12 read more about doThrow () | doAnswer () method of the information.

6. Invoke sequential verification

 // A. A single mock object whose methods must be called in A particular order
 List singleMock = mock(List.class);

 // Use a single mock object
 singleMock.add("was added first");
 singleMock.add("was added second");

 // Create an inOrder validation for a single mock object
 InOrder inOrder = inOrder(singleMock);

 // The code below confirms that the add method was called "was added first" and "was added second"
 inOrder.verify(singleMock).add("was added first");
 inOrder.verify(singleMock).add("was added second");

 // B. Mock objects whose methods must be called in a particular order
 List firstMock = mock(List.class);
 List secondMock = mock(List.class);

 // Use mock objects
 firstMock.add("was called first");
 secondMock.add("was called second");

 // create an inOrder object through multiple mock objects that need to be validated inOrder
 InOrder inOrder = inOrder(firstMock, secondMock);

 // The following code verifies that firstMock is called before secondMock
 inOrder.verify(firstMock).add("was called first");
 inOrder.verify(secondMock).add("was called second");

 //A + B can be mixed together
Copy the code

Sequential validation is flexible – you don’t have to validate all interactions one by one, but only those interactions you are interested in sequentially.

In addition, you can create an InOrder object that passes only moC K objects related to ordered validation.

7. Make sure there is no interaction on the mock object

 // Use mock objects - only mockOne is interactive
 mockOne.add("one");

 // Common validation
 verify(mockOne).add("one");

 // Verify that a method has never been called
 verify(mockOne, never()).add("two");

 // Verify that other methods never send interactions
 verifyZeroInteractions(mockTwo, mockThree);
Copy the code

8. Look for extra calls

 // Use mock objects
 mockedList.add("one");
 mockedList.add("two");

 verify(mockedList).add("one");

 // The following validation will fail
 verifyNoMoreInteractions(mockedList);
Copy the code

A word of warning: Users who have done a lot of classic Expect -run-verify mocks will often use verifyNoMoreInteractions(), even in every test method. VerifyNoMoreInteractions () is not recommended for use in every test method. VerifyNoMoreInteractions () is a handy assertion from the Interaction test kit. Use it only when relevant. Abusing it can lead to over-specified tests that are not easy to maintain.

Also see never()- it is more explicit and communicates intent well.

9. Simple mocks@Mockannotations

  • Minimize duplicate mock creation code.
  • Make the test class more readable.
  • Make validation errors easier to read because field names are used to identify mocks.
public class ArticleManagerTest {

       @Mock private ArticleCalculator calculator;
       @Mock private ArticleDatabase database;
       @Mock private UserProvider userProvider;

       private ArticleManager manager;

       @org.junit.jupiter.api.Test
       void testSomethingInJunit5(@Mock ArticleDatabase database) {
             //do something}}Copy the code

Important: The following code needs to be somewhere in the base class or test runner:

 MockitoAnnotations.openMocks(testClass);
Copy the code

You can use the built-in runner: MockitoJUnitRunner or rule: MockitoRule. For JUnit5 tests, see the JUnit5 extensions described in section 45.

Read more here: MockitoAnnotations

10. The stub calls continuously(the iterator – style stubbing)

Sometimes we need to stub with different return values/exceptions for the same method call. A typical use case might be a mock iterator. The original version of Mockito did not have this feature to facilitate simple mocks. For example, you can use Iterable or simply collections instead of iterators. These provide a natural way to stub (such as using real collections). However, there are rare cases where stub calls can be useful:

 when(mock.someMethod("some arg"))
   .thenThrow(new RuntimeException())
   .thenReturn("foo");

 // First call: throws a runtime exception:
 mock.someMethod("some arg");

 // Second call: prints "foo"
 System.out.println(mock.someMethod("some arg"));

 // Any subsequent calls: will output "foo" (the last stub will take effect).
 System.out.println(mock.someMethod("some arg"));

Copy the code

Alternatively, it can be a shorter version of a continuous stub:

 when(mock.someMethod("some arg")).thenReturn("one"."two"."three");
Copy the code

Warning: If instead of successive.thenreturn () calls, multiple stubs with the same matcher or argument are used, the later stubs will override the previous one:

 // All mock. SomeMethod ("some arg") calls return "two"
 when(mock.someMethod("some arg"))
   .thenReturn("one")
 when(mock.someMethod("some arg"))
   .thenReturn("two")
 
Copy the code

11.Use the callback for stubs

Allow stubbing using the Answer interface.

Another controversial feature was not originally included in Mockito. We recommend simply using thenReturn() or thenThrow() for stubs, which should be enough to test/test drive any clean and simple code. However, if you do need to use a generic Answer interface stub, here’s an example:

 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); }});// The following will output "called with arguments: [foo]"
 System.out.println(mock.someMethod("foo"));
 
Copy the code

12. doReturn()| doThrow()| doAnswer()| doNothing()| doCallRealMethod()Methods the family

The stub void method requires a different method than when(Object), because the compiler does not like when() parentheses using methods that return void……

Use doThrow() when you want the stub void method to throw an exception:

   doThrow(new RuntimeException()).when(mockedList).clear();

   // The following code throws a RuntimeException:
   mockedList.clear();
 
Copy the code

You can use doThrow(), doAnswer(), doNothing(), doReturn() and doCallRealMethod() in place of when(), for any method. When you have to

  • The stub void method
  • Methods for stub Spy objects (see below)
  • Stub the same method multiple times to change the behavior of the mock object during testing.

But for all stub calls when(), you might prefer to use these alternatives.

Read more about these methods:

doReturn(Object)

doThrow(Throwable...)

doThrow(Class)

doAnswer(Answer)

doNothing()

doCallRealMethod()

13.Monitor real objects: Use SPY

You can monitor real objects (using SPY). When you use SPY, the real method is called (unless the method is stubbed).

Spy should be used sparingly, for example, occasionally when dealing with legacy code.

Monitoring of real objects can be associated with the concept of “partial mocks.” Prior to version 1.8, Mockito Spy was not really a partial mock. The reason is that we consider some mocks to be code odors. At some point, we found legitimate use cases for some mocks (third party interfaces, temporary refactoring of legacy code).

   List list = new LinkedList();
   List spy = spy(list);

   // You can stub some methods:
   when(spy.size()).thenReturn(100);

   // Use spy to call real methods
   spy.add("one");
   spy.add("two");

   // Prints the first element of "one" -list
   System.out.println(spy.get(0));

   // the size() method has been stubbed - output 100
   System.out.println(spy.size());

   // You can also verify
   verify(spy).add("one");
   verify(spy).add("two");
 
Copy the code

Important issues for monitoring real objects:

  1. Sometimes it is impossible or impractical to use when(Object) for stubbed SPY objects. So please consider when using spy use doReturn | Answer | Throw () stub methods. Example:

       List list = new LinkedList();
       List spy = spy(list);
    
       / / the code below is impossible: the real function will be called, spy. Get (0) throws IndexOutOfBoundsException (the list is still empty)
       when(spy.get(0)).thenReturn("foo");
    
       // You need to use doReturn() to remove stubs
       doReturn("foo").when(spy).get(0);
     
    Copy the code
  2. Mockito does not pass the call to a real instance, but actually creates a copy of it. Therefore, if you keep real instances and interact with them, you should not expect the person being monitored to know about those interactions and their impact on the state of the real instance. Correspondingly, when the unstubbed (no stub) method is called on the SPY object but not on the real instance, you will not see any impact on the real instance.

  3. Note the final method. Mockito does not mock final methods, so the bottom line is: when you monitor real objects + try stub final methods = trouble. You will also not be able to validate these methods.

14. Has not changedThe default return value of the stub call(Since 1.7)

You can create return values for mock objects with specified policies. This is such an advanced feature that you don’t usually need it to write decent tests. However, it is useful for dealing with legacy systems.

// It is returned by default, so ** is only used when you ** call the non-stub method **.
Foo mock = mock(Foo.class, Mockito.RETURNS_SMART_NULLS);
// Custom return value policy
Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
Copy the code

Read more about this interesting Answer implementation: RETURNS_SMART_NULLS

15. For further assertionCapture parameters(Since 1.8.0)

Mockito implements the natural Java-style validation of parameter values by using the equals() method. This is also the recommended way to match parameters, because it makes testing clean and easy. In some cases, it may be helpful to assert certain parameters after actual validation. Such as:

   ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
   verify(mock).doSomething(argument.capture());
   assertEquals("John", argument.getValue().getName());
Copy the code

Warning: It is recommended to use ArgumentCaptor with validation, but not with stubs. Using stub ArgumentCaptor can reduce the readability of the test, because captor is created outside the assertion (aka validation or “then”) block. It also reduces defect location because no parameters are captured if the stub method is not called.

ArgumentCaptor is, in a way, related to custom argument matchers (see Javadoc for the ArgumentMatcher class). Both techniques can be used to ensure that certain parameters are passed to mock objects. However, ArgumentCaptor may be more appropriate in the following cases:

  • Custom parameter matchers are unlikely to be reused
  • You only need it to assert the parameter values to complete the validation

A custom ArgumentMatcher is usually better for stubs.

16.Real part of the mock(Since 1.8.0)

Finally, after much internal debate and discussion on the mailing list, Mockito added support for partial mocks. Previously we thought of some mocks as code smells. However, we found some legitimate use cases for mocks.

Prior to version 1.8, Spy () didn’t produce real partial mocks, which confused some users. Read more about Spy: Get the Spy (Object) method here or in Javadoc.

    // You can create part of the mock using the spy() method
    List list = spy(new LinkedList());

    // You can optionally enable some of the mock functionality in mock:
    Foo mock = mock(Foo.class);
    // First make sure the real implementation is secure.
    // If the real implementation throws exceptions or relies on special objects then you will run into trouble.
    when(mock.someMethod()).thenCallRealMethod();
  
Copy the code

As usual, you’ll read part of the mock warning: Object-oriented programming reduces complexity by dividing it into separate, specific SRPy objects. How do partial mocks fit into this paradigm? Well, it just doesn’t have…… A partial mock usually means that complexity has been transferred to different methods on the same object. In most cases, this is not how you want to design your application.

However, there are rare cases where partial mocks come in handy: dealing with code that you can’t easily change (third-party interfaces, temporary refactoring of legacy code, etc.) But I wouldn’t use partial mocks for new, test-driven & well-designed code.

17.Reset the mock(Since 1.8.0)

Smart Mockito users rarely use this feature because they know it could be a sign of poor testing. Typically, you don’t need to reset a mock, just create a new mock for each test method.

Consider writing simple, small, focused test methods instead of reset() in lengthy, over-specified tests. ** The first potential code smell is reset() in the middle of the test method. ** This may mean that you are testing too much. Follow your test method’s whisper: “Please let’s keep small and focus on a single action.” There are several topics about it on the Mockito mailing list.

The only reason we added the reset() method was because container-injected mocks could be used. For more information, see frequently asked Questions (here).

Don’t hurt yourself. In the middle of the reset() test method is code smell (you might be testing too much).

   List mock = mock(List.class);
   when(mock.size()).thenReturn(10);
   mock.add(1);

   reset(mock);
   // At this point the mock forgets all interactions and stubs
Copy the code

18.Use of troubleshooting and validation frameworks(Since 1.8.0)

First of all, if you have any questions, I encourage you to read the Mockito FAQ: HTTPS: / / github.com/mockito/mockito/wiki/FAQ

If there is a problem, you can also release to mockito mailing list: HTTPS: / / groups.google.com/group/mockito

Next, you should learn all about Mockito validation if you want to use it correctly. However, there is a problem here. Read validateMockitoUsage() Javadoc.

19.An alias for behavior-driven development(Since 1.8.0)

You can write behavior-driven development-style tests using **//given //when //then** comments as an essential part of the test method. This is exactly how we write tests, and we strongly encourage you to do so!

Start from here learning BDD: HTTPS: / / en.wikipedia.org/wiki/Behavior-driven_development

The problem is that the current stub API and the when keyword don’t integrate well with **//given //when //then annotations. This is because the stub belongs to the given component of the test, not the WHEN component of the test. So the BDDMockito class introduces an alias so that you can stub method calls using the bddMockito.Given (Object) method. Now it really integrates well with the given ** components of BDD style testing!

Here’s what the test looks like:

 import static org.mockito.BDDMockito.*;

 Seller seller = mock(Seller.class);
 Shop shop = new Shop(seller);

 public void shouldBuyBread(a) throws Exception {
   //given: alias of the when method
   given(seller.askForBread()).willReturn(new Bread());

   //when
   Goods goods = shop.buyBread();

   //then
   assertThat(goods, containBread());
 }
 
Copy the code

20. Serializable mock(Since 1.8.1)

Mocks can be serialized. Using this feature, you can mock where you need serializable dependencies.

Warning: This should rarely be used for unit testing.

This behavior is implemented for a specific use case of the BDD specification with unreliable external dependencies. This is in a Web environment where objects from external dependencies are serialized to be passed between layers.

Create a serializable mock using MockSettings. Serializable () :

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

A mock can be serialized, assuming the class meets all the normal serialization requirements.

Because of the spy (…). Methods do not accept an overloaded version of MockSettings, so more effort is required to make the actual object Spy serializable. Don’t worry, you’ll almost never use it.

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

21. New notes:@Captor.@Spy.@InjectMocks(Since 1.8.3)

Version 1.8.3 brings new comments that may be useful at times:

  • @captor simplifies ArgumentCaptor – useful when the argument to be captured is an obnoxious generic class and you want to avoid compiler warnings
  • @spy – You can use this instead of Spy (Object).
  • InjectMocks- Automatically inject mock or Spy fields into test objects.

Note that @injectmocks can also be used in conjunction with the @spy annotation, which means Mockito will InjectMocks into the part of the mock under test. This complexity is another good reason why you should only use partial mocks as a last resort. See point 16 on partial mocks.

All new annotations in only MockitoAnnotations. OpenMocks (Object) on processing. Like @ Mock comments, you can use the built-in runner: MockitoJUnitRunner or rule: MockitoRule.

22.Timeout validation(Since 1.8.5)

Timeout validation is allowed. It waits a specified amount of time to validate the desired interaction, rather than failing immediately if it hasn’t happened yet. May be useful for testing under concurrent conditions.

This feature should be used sparingly – find a better way to test your multithreaded system.

Not yet implemented for use with InOrder validation.

Example:

   // Handle when someMethod() is called less than 100ms
   Exit immediately when validation is satisfied (for example, maybe not 100 ms)
   verify(mock, timeout(100)).someMethod();
   // The above code can also be written as:
   verify(mock, timeout(100).times(1)).someMethod();

   // When someMethod() is called in less than 100ms, 2 passes
   verify(mock, timeout(100).times(2)).someMethod();

   // This is equivalent to the code above:
   verify(mock, timeout(100).atLeast(2)).someMethod();
 
Copy the code

23.use@Spies.@InjectMocksAutomatically instantiate objectsAnd have aGood constructor injection(After 1.9.0)

Mockito will now try to instantiate objects using @Spy and instantiate fields of InjectMocks using constructor injection, setter injection, or field injection.

To take advantage of this feature, you need to use MockitoAnnotations. OpenMocks (Object), MockitoJUnitRunner or MockitoRule.

Read more about the available techniques and injection rules in InjectMocks’ Javadoc.

 @Spy BeerDrinker drinker = new BeerDrinker();
 // You can also write:
 @Spy BeerDrinker drinker;

 // @injectmocks annotations can also be used:
 @InjectMocks LocalPub;
 
Copy the code

24.Single stub(Since 1.9.0)

Mockito now allows you to create mocks on stubs. Basically, it allows you to create a stub in a single line of code. This helps keep the test code clean. For example, some boring stubs can be created and stubbed during field initialization in the test:

 public class CarTest {
   Car boringStubbedCar = when(mock(Car.class).shiftGear()).thenThrow(EngineNotStarted.class).getMock();

   @Test public void should... {}
 
Copy the code

25.Stub validation is ignored(Since 1.9.0)

Mockito now allows stubs to be ignored for validation. Sometimes useful in conjunction with verifyNoMoreInteractions() or inOrder() validation. Helps to avoid redundant validation of stub calls – generally we are not interested in validating stubs.

Warning, ignoreStubs() may cause verifyNoMoreInteractions(ignoreStubs(…)) ) overuse; Remember, for the reasons outlined in The verifyNoMoreInteractions() Javadoc, Mockito does not recommend using the verifyNoMoreInteractions(Object…) for every test. .

Some examples:

 verify(mock).foo();
 verify(mockTwo).bar();

 // Ignore all stub methods:
 verifyNoMoreInteractions(ignoreStubs(mock, mockTwo));

 // Create InOrder, which ignores the stub
 InOrder inOrder = inOrder(ignoreStubs(mock, mockTwo));
 inOrder.verify(mock).foo();
 inOrder.verify(mockTwo).bar();
 inOrder.verifyNoMoreInteractions();
 
Copy the code

Can be in ignoreStubs (Object…). Find advanced examples and more details in javadoc.

26. mockingDetails(2.2.x improvement)

Mockito provides apis to examine the details of mock objects. This API is useful for advanced users and mock framework integrators.

   // Determine whether a particular object is a mock or a spy:
   Mockito.mockingDetails(someObject).isMock();
   Mockito.mockingDetails(someObject).isSpy();

   // Get details such as mock type or default Answer:
   MockingDetails details = mockingDetails(mock);
   details.getMockCreationSettings().getTypeToMock();
   details.getMockCreationSettings().getDefaultAnswer();

   // Get the mock object's interaction or stub:
   MockingDetails details = mockingDetails(mock);
   details.getInvocations();
   details.getStubbings();

   // Prints all interactions (used stubs, unused stubs)
   System.out.println(mockingDetails(mock).printInvocations());
 
Copy the code

For more information, see MockingDetails.

27.Delegate calls to real objects(Since 1.9.5)

You can use it to monitor or partially mock objects that are difficult to mock or monitor using the normal SPY API. Starting with Mockito 1.10.11, delegates may or may not be of the same type as mocks. If the types are different, a matching method needs to be found on the delegate type, otherwise an exception is thrown. Possible use cases for this feature:

  • Final class but with an interface
  • A custom proxy object has been defined
  • Special objects with finalize methods, that is, avoid executing twice

Differences with normal SPY:

  • The regular SPY (Spy (Object)) contains all the state and called methods from the monitored instance. The monitored instance is only used for mock creation to replicate state from it. If you call a method on a regular SPY, and it calls other methods on this Spy internally, those calls are remembered for validation, and they can be effectively stubbed.
  • A delegate mock simply delegates all methods to the delegate class. The delegate class is always in use because methods are delegated to it. If you call a method on a mock of a delegate class, and it calls other methods on that mock internally, those calls are not remembered for validation, and the stub does not affect them. Mock delegates are not as powerful as regular Spy, but they are useful when regular Spy cannot be created.

In AdditionalAnswers. DelegatesTo (Object) in the document for more information.

28. MockMaker API(Starting from 1.9.5)

Driven by requirements and patches from Google Android people, Mockito now provides an extension point that allows replacement of the proxy generation engine. By default, Mockito uses Byte Buddy to create dynamic proxies.

Extension points are for advanced users who want to extend Mockito. For example, dexmaker for The Android version of Mockito can now be used to help with testing.

For more details, motivations, and examples, see MockMaker.

29. BDD style verification(Since 1.10.0)

Enable behavior-driven Development (BDD) style validation by starting validation with the BDD then keyword.

 given(dog.bark()).willReturn(2); // when ... then(person).should(times(2)).ride(bike); 
Copy the code

For more information and examples, see bddmockito.then (Object)

30.Monitor or Mock abstract classes (since 1.10.12, further enhanced in 2.7.13 and 2.7.14)

It is now easy to monitor abstract classes. Note that the overuse of Spies implies an oddity in code design (see Resources Spy (Object)).

Previously, only object instances could be monitored. The new API makes it possible to use constructors when creating mock instances. This is particularly useful for mock abstract classes, since users no longer need to provide an instance of the abstract class. Currently only parameterless constructors are supported, let us know if that’s not enough.

 // handy API, newly loaded spy() method: SomeAbstract spy = spy(someabstract.class); //Mocking interface default (available from 2.7.13) Function Function = spy(function.class); // Robust API from Settings Builder: OtherAbstract spy = mock(OtherAbstract.class, withSettings() .useConstructor().defaultAnswer(CALLS_REAL_METHODS)); //Mock an abstract class, UseConstructor (available from 2.7.14) SomeAbstract spy = mock(someabstract.class, withSettings().useconstructor ("arg1", 123).defaultAnswer(CALLS_REAL_METHODS)); //mock a non-static InnerAbstract class. InnerAbstract spy = mock(InnerAbstract. Class, withSettings() .useConstructor().outerInstance(outerInstance).defaultAnswer(CALLS_REAL_METHODS));
Copy the code

For more information, please refer to the MockSettings. UseConstructor (Object)… .

31. Mockito can be simulated across class loadersserialization/deserialization(Since 1.10.0)

Mockito introduced serialization across class loaders. As with any other form of serialization, all types in the mock hierarchy must be serializable, including Answer. This is an optional setting because this serialization mode requires more work.

 // Use normal serialization mock(book.class, withSettings().serializable()); // Serialize mock(book.class, withSettings().serializable(ACROSS_CLASSLOADERS)) with class loaders;
Copy the code

For more detailed information, please refer to the MockSettings. Serializable (SerializableMode).

32.Better general support for deep stubs (since 1.10.0)

Deep stubs have been improved to find generic information available in classes. This means that such classes can be used without mock behavior.

 class Lines extends List<Line> {     / /... } lines = mock(Lines.class, RETURNS_DEEP_STUBS); // Now Mockito this is not an object but a Line Line Line = lines.iterator().next();
Copy the code

Note that in most cases, a mock that returns a mock is wrong.

33. Mockito JUnit Rule (from 1.10.17)

Mockito now provides a JUnit rule. Until now there were two ways to initialize annotation fields in JUnit, via Mockito annotations @mock @spy @injectMocks etc.

  • with@RunWith(MockitoJUnitRunner.class)Annotate a JUnit test class
  • in@BeforeMethod callMockitoAnnotations.openMocks(Object)

Now you can choose to use rule:

 @RunWith(YetAnotherRunner.class) public class TheTest {     @Rule public MockitoRule mockito = MockitoJUnit.rule();     // ... } 
Copy the code

For more information, see mockitojunit.rule ().

34.Switch-plug-inTo enable theordisable(Since October 1, 2015)

The incubation feature makes it a way in Mockito to allow switching between mockito-plugins. More information is available here at PluginSwitch.

35.User-defined authentication failure information(Since 2.1.0)

Allows you to specify a custom message to print when validation fails.

Example:

 Verify (mock, description("This will print on failure").somemethod (); // Verify (mock, times(2).description("someMethod should be called twice")).somemethod ();
Copy the code

36. Java 8 Lambda matcher support(Since 2.1.0)

You can use Java 8 lambda expressions and ArgumentMatcher to reduce your dependence on ArgumentCaptor. If you need to verify that the input to a function call on a mock object is correct, you will usually use ArgumentCaptor to find the arguments used and then make subsequent assertions on them. While this can be useful for complex examples, it is also verbose.

It’s easy to write a lambda expression to express a match. When used with argThat, the argument to the function is passed to the ArgumentMatcher as a strongly typed object, so you can do anything with it.

Example:

 Verify (list, times(2)).add(argThat(string -> string.length() < 5)); // The Java7 equivalent, It's not very neat. Verify (list, times(2)).add(argThat(new ArgumentMatcher(){ public boolean matches(String arg) { return arg.length() < 5; }})); // More complex Java 8 examples - you can specify the complex validation behavior verify(target, times(1)).receiveComplexObject(argThat(obj -> obj.getSubObject().get(0).equals("expected"))); // You can also use this to define mock behavior with different inputs, in which case if the input list is less than 3 items, ThenReturn (null) when(mock.somemethod (argThat(list -> list.size()<3)).thenReturn(null);
Copy the code

37. Java 8 Custom Answer support(Since 2.1.0)

Because the Answer interface has only one method, it can be implemented very simply in Java 8 using lambda expressions. The more you need to use the parameters of a method call, the more you need to use InvocationOnMock.

Example:

 // Return the Answer doAnswer(Invocation -> 12).when(mock).dosomething (); // Use the Answer of the argument - convert to the correct type you expect - in this case, Return the length of the second argument // This quickly resolves the long argument conversion doAnswer(Invocation -> ((String) Invocation.getargument (1)).length())) .when(mock).doSomething(anyString(), anyString(), anyString());
Copy the code

For convenience, you can write custom Answer/ Actions that use Java 8 lambdas as arguments to method calls. Even in Java 7, reducing these custom answers based on typed interfaces can reduce boilerplate code. In particular, this approach will make it easier to test functions that use callbacks. The methods answer and answerVoid can be used to create answer. They rely on the org.mockito.stubbing related Answer interface to support answers with up to five parameters.

Example:

 // The mock interface has the following functions: void execute(String operand, Callback Callback); // The example callback has a function and the class under test depends on this callback when it is called void receive(String item); / / Java 8 - way 1 doAnswer (AdditionalAnswers. AnswerVoid ((operand, callback) -> callback.receive("dummy")) .when(mock).execute(anyString(), any(Callback.class)); // Java 8 - mode 2 - assuming classes have been statically imported: AdditionalAnswers doAnswer(answerVoid((String operand, Callback callback) -> callback.receive("dummy")) .when(mock).execute(anyString(), any(Callback.class)); Private static void dummyCallbackImpl(String Operation, String operation); Callback callback) { callback.receive("dummy"); } doAnswer(answerVoid(TestClass::dummyCallbackImpl) .when(mock).execute(anyString(), any(Callback.class)); // Java 7 doAnswer(answerVoid(new VoidAnswer2() { public void answer(String operation, Callback callback) { callback.receive("dummy"); }})).when(mock).execute(anyString(), any(Callback.class)); // Use answer() to return a possible value and a non-void version of the function interface, that is, the mock interface looks like this: Boolean isSameString(String input1, String input2); Java 8 doAnswer(additionalanswers.answer ((input1, input2) -> input1.equals(input2)))) .when(mock).execute(anyString(), anyString()); // Java 7 doAnswer(answer(new Answer2() { public String answer(String input1, String input2) { return input1 + input2; }})).when(mock).execute(anyString(), anyString());
Copy the code

38.Retention of metadata and generic types(Since 2.1.0)

Mockito now retains annotations on mock method types and common metadata. Previously, mock types did not retain annotations of types unless they were explicitly inherited and never retained annotations of methods. Therefore, the following conditions now hold:

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

With Java 8, Mockito now retains type annotations. This is the default behavior and may not work if you use the alternative method MockMaker.

39.Mock Final classes, enums, and final methods(Since 2.1.0)

Mockito now provides an optional support for Mock final classes and methods: Incubating. This is a remarkable improvement and demonstrates Mockito’s abiding commitment to improving the testing experience. Our goal was to Mockito “only work” with final classes and methods. Previously they were considered mockable to prevent users from mocking. We’ve already started discussing how to enable this feature by default. For now, this feature is still optional as we await more feedback from the community.

Instead of creating a new class to represent mocks, the alternative mock generator uses a combination of Java Instrumentation APIS and subclasses. This way, you can mock final classes and methods.

This mock generator is ** off by default, ** because it is based on a completely different mock mechanism and requires more feedback from the community. It can use mockito extension mechanism explicit activation, simply create a contains the value in the classpath for mock – maker – the inline/mockito – extensions/org. Mockito. Plugins. MockMaker file.

For convenience, the Mockito team provides an artifact with this mock generator pre-configured. Instead of using the mockito-core artifact, include the Mockito-inline artifact in your project. Note that once mocks of final classes and methods are integrated into the default Mock generator, this artifact may stop being used.

A few notes worth noting about this mock Marker:

  • Mock Final classes and enumerations are not compatible with mock Settings, for example:
    • Explicit serialization supportwithSettings().serializable()
    • Additional interfaceswithSettings().extraInterfaces()
  • Some methods cannot be mocked
    • java.*Methods visible in the package
    • nativemethods
  • This mock maker is designed around Java Agent runtime attachments; This requires a compatible JVM, which is part of the JDK (or Java 9 VM). However, when running on non-JDK VMS prior to Java 9, it can be added manually when the JVM is startedByte Buddy Java proxy JAR-javaagentParameter usage.

If you are interested in this function more detailed information, please read org. Mockito. Internal. Creation. Bytebuddy. InlineByteBuddyMockMaker javadoc.

40.Use “tougher” Mockito to increase productivity and write more concise tests(since 2.+)

For a quick look at how “tougher” Mockito improves your productivity and makes your tests clearer, see:

  • Strictness use JUnit4 rules for strict stubs – use Strictness.STRICT_STUBS MockitoRule. Strictness (Strictness)
  • Use JUnit4 Runner for strict stubs –MockitoJUnitRunner.Strict
  • Use the JUnit5 extension for strict stubs –org.mockito.junit.jupiter.MockitoExtension
  • Use TestNGListener MockitoTestNGListener for strict stubs
  • If you can’t use Runner /rule, use MockitoSession for strict stubbing
  • There is no need to use MockitoJUnitRunner for stub detection
  • Stub parameter mismatch warning, recorded in MockitoHint

By default, Mockito is a “loose” mock framework. You can interact with mocks without setting any expectations up front. This is intentional, and it improves the quality of testing by forcing users to specify what they want stubs/validation to do. It’s also intuitive, easy to use, and blends well with the “Given,” “When,” and “then” templates of clean test code. This is also different from the classic mock frameworks of the past, which were “strict” by default.

Being “loose” by default makes Mockito tests sometimes harder to debug. In some cases, a misconfigured stub (for example, with the wrong parameters) forces the user to run tests using the debugger. Ideally, test failures are obvious and no debugger is needed to determine the root cause. Starting with version 2.1, Mockito has gained new features that push the framework toward “rigor.” We wanted Mockito to provide great debuggability without losing its core mock style, optimized for simplicity, clarity, and clean test code.

Help Mockito! Try new features, give us feedback, and join the discussion about Mockito rigor on GitHub question 769.

41.High-level public API for framework integration (since 2.10.+)

In the summer of 2017, we decided that Mockito should provide a better API for high-level framework integration. The new API is not for users who want to write unit tests. It is suitable for other testing tools and mock frameworks that need to extend or wrap Mockito with some custom logic. During design and implementation (Issue 1110), we developed and changed the following public API elements:

  • New MockitoPlugins- enables framework integrators to access the default Mockito plug-in. This is useful when you need to implement a custom plug-in, such as MockMaker, and delegate some behavior to the default Mockito implementation.
  • New MockSettings.build(Class)- Creates an immutable view of mock Settings that Mockito will use later. Used to create calls using InvocationFactory or when implementing a custom MockHandler.
  • newMockingDetails.getMockHandler()– Other frameworks can mock programmatically using mock handlersIs the mock objectOn.
  • New MockHandler. GetMockSettings () – used to create a mock object for setting.
  • newInvocationFactory– Provides creationInvocationObject instance method. For the need to mock programmaticallyIs the mock objectFramework integration of method calls on.
  • New MockHandler. GetInvocationContainer () – provide for there is no way (marker interface) call container object access. The container is needed to hide the internal implementation and avoid leaking it to the public API.
  • changeStubbing– It now expandsAnswerInterface. It is backward compatible because the Stubbing interface is not extensible (see Resources)NotExtensible). This change should be seamless for our users.
  • deprecatedInternalMockHandler– To accommodate API changes, we need to deprecate this interface. The interface was always documented internally and we have no evidence that it was used by the community. Deprecation should be completely seamless for our users.
  • NotExtensible- indicates to the user that she should not provide public annotations for a custom implementation of a given type. Help framework integrators and our users understand how to use the Mockito API safely.

Do you have any feedback? Please comment on issue 1110.

42.New API for integration: Listening for validation start events (since 2.11.+)

Framework integration such as Spring Boot requires a common API to handle double-agent use cases (Question 1191). We added:

  • Enable new VerificationStartedListener and VerificationStartedEvent object, frame integrators can use its replacement is used to validate the mock object. The primary driver use case is the Spring Boot integration. For more information, please refer to the VerificationStartedListener Javadoc.
  • New methods of public MockSettings. VerificationStartedListeners (VerificationStartedListener…). Allows you to provide a validation-initiated listener at mock creation time.
  • MockingDetails.getMock()New convenience methods have been added to enableMockingDetailsThe API is more complete. We found this approach useful in implementation.

43.New API for integration: available for testing frameworksMockitoSession(since 2.15.+)

MockitoSessionBuilder and MockitoSession are enhanced by test framework integration (e.g. MockitoRule for JUnit) to achieve reuse:

  • MockitoSessionBuilder.initMocks(Object…) Allows multiple test class instances to be passed in to initialize the use of Mockito annotations (such as Mock. This approach is useful for advanced framework integration, such as JUnit Jupiter, when tests use multiple (such as nested) test class instances.
  • MockitoSessionBuilder. Name (String) allows for the name of the test framework to MockitoSession, it will be used for printing when using warning Strictness. The name of the WARN.
  • MockitoSessionBuilder. Logger (MockitoSessionLogger) can be customized for the complete generated reminder/alarm when the mock recorder (for testing and connected by the JUnit test framework provided by the report function such as Jupiter is useful).
  • MockitoSession. SetStrictness (Strictness) allow change MockitoSession one-off scenario rigor, for example, it can do for all the test configuration default rigour in the class, but you can change the single or several test rigor.
  • MockitoSession.finishMocking(Throwable)Added to avoid possible confusion because there are multiple competition failures. When providing thefailurenotnull, it will disable certain checks.

44.Have been abandoned,org.mockito.plugins.InstantiatorProviderBecause it would leak the internal API. It’s replaced by thetaOrg. Mockito. Plugins. InstantiatorProvider2 (Since 2.15.4)

InstantiatorProvider returns an internal API. Therefore it is deprecated and replaced by InstantiatorProvider2. The old Instantiator providers will continue to work, but it is recommended to switch to the new API.

45.New JUnit Jupiter (JUnit5+) extension

To integrate with JUnit Jupiter (JUnit5+), use the org.mockito: mockito-junit-Jupiter artifact. For more information about the use of integration, see the JavaDoc of MockitoExtension.

46.The newMockito.lenient()andMockSettings.lenient()(from 2.20.0)

Strict stub functionality has been provided since early Mockito 2. It’s very useful because it drives clearer testing and increases productivity. Strict stubs report unnecessary stubs, detect stub parameter mismatches and make the test more DRY (Strictness.STRICT_STUBS). There’s a tradeoff: In some cases, you might get false negatives from strict stubs. To resolve these situations, you can now configure specific stubs to be loose, while all other stubs and mocks use strict stubs:

   lenient().when(mock.foo()).thenReturn("ok"); 
Copy the code

If you want all stubs on a given mock to be loose, you can configure the mock accordingly:

   Foo mock = Mockito.mock(Foo.class, withSettings().lenient()); 
Copy the code

For more information, see Lenient (). Let us know how you find new features by opening GitHub Questions for discussion!

47.New API for clearing mock state in inline mocks (as of 2.25.0)

Inline mocks can cause memory leaks in certain, rare cases (problem #1619). There is no clean way to completely alleviate the problem. Therefore, we introduced a new API to explicitly clear mock state (only meaningful in inline mocks!). . Please refer to the MockitoFramework. ClearInlineMocks () the sample usage. If you have feedback or better ideas on how to solve the problem, please contact.

48.Mock static methods(Since 3.4.0)

With inline Mock Maker, you can mock static method calls in the current thread and user-defined scope. In this way, Mockito ensures that tests run simultaneously and sequentially do not interfere with each other. To ensure that static mocks remain temporary, it is recommended to define scopes in try-with-resources constructs. In the following example, the static method of class Foo returns Foo unless you mock:

 assertEquals("foo", Foo.method()); try (MockedStatic mocked = mockStatic(Foo.class)) {     mocked.when(Foo::method).thenReturn("bar");     assertEquals("bar", Foo.method());     mocked.verify(Foo::method); } assertEquals("foo", Foo.method()); 
Copy the code

Because the static mock defines the scope, once the scope is released, it returns its original behavior. To define mock behavior and validate static method calls, use the object returned by MockedStatic.

49.Mock object construction(Since 3.5.0)

With inline Mock Maker, you can generate mocks on constructor calls in the current thread and user-defined scope. In this way, Mockito ensures that tests run simultaneously and sequentially do not interfere with each other. To ensure that the mock constructor remains temporary, it is recommended to define scopes in try-with-resources constructs. In the following example, the constructed Foo class generates a mock:

 assertEquals("foo".new Foo().method()); try (MockedConstruction mocked = mockConstruction(Foo.class)) { 		Foo foo = new Foo(); 		when(foo.method()).thenReturn("bar"); 		assertEquals("bar", foo.method()); 		verify(foo).method(); } assertEquals("foo".new Foo().method()); 
Copy the code

Because the mock object construct defines the scope, once the scope is released, the object construct returns its original behavior. To define mock behavior and validate method calls, use the objects returned by MockedConstruction.