This is my second article on getting started

In writing the test may find that we want to test a method, called the other interface module, there are two things to make our test, one is in the process of the test found that rely on other modules haven’t finish development, 2 it is to rely on is the online database module, such as should not be in a unit test data in the process of operation, In both cases, we can’t call the other module’s API, so we need to mock the other module’s interface.

To mock is to use a fake object to simulate the behavior of some object that is not easy to obtain or construct. Mockit is a common Mock library in the Java domain that makes it easy to Mock an object quickly.

Mockit Creates mock objects

Mockit can create two types of mock objects:

  1. The interface of an object created through the @Mock annotation or a static method is fully simulated
  2. Objects created with @spy or the static method Spy have interfaces that are partially emulated. Only the interfaces that are specified to be emulated are emulated

Mock objects can be created in one of three ways:

  1. Mockito.mock(XXXX), mockito.spy (XXXX)
  2. Annotations @mock, @Spy
  3. Spring @ MockBean in the boot

Mockit mock method

when()

When we get a mock object, we can simulate the methods of the mock object, given its return value or other behavior, with the main interface as

  • when(xxx).thenReturn(xxxx)
  • when(xxx).thenThrow(xxxx)
  • when(xxx).thenAnswer(Answer<> a)

The following is an example:

public class DbConnect{
  public int getNum(int id);
}

public void mockDemo(a){
  DbConnect dbConnect = Mockito.mock(DbConnect.class);
  when(dbConnect(1)).thenReturn(5);
  Assert(5, dbConnect.getNum(1));
}
Copy the code

The special one is the thenAnswer interface, which requires us to pass an Answer callback object with the Answer method in it to specify the specific mock behavior. The Answer interface is as follows:

public interface Answer<T> {
    / * * *@param invocation the invocation on the mock.
     *
     * @return the value to be returned
     *
     * @throws Throwable the throwable to be thrown
     */
    T answer(InvocationOnMock invocation) throws Throwable;
}
Copy the code

Since Java8 introduced lambda expressions, we can easily write callback methods, as shown in the following example:

when(mock.someMethod(anyString())).thenAnswer(
    (invocation) -> {
        Object[] args = invocation.getArguments();
        Object mock = invocation.getMock();
        return "called with arguments: "+ Arrays.toString(args); }}); System.out.println(mock.someMethod("foo"));
Copy the code

Obviously, the above example outputs “called with arguments: [foo]”

verify()

The verify() interface is used to check that the mock method is called as many times as expected for a given argument

verify(mock, times(5)).someMethod("was called five times");
      
verify(mock, atLeast(2)).someMethod("was called at least two times");
Copy the code

Mockit injects mock objects

As mentioned above, when we want to test A method of object, rely on the object B method, we use this way to create A mock object, you need to mock object into A B object, to A method for unit testing, and the way of mentioned above to create one to one correspondence, Mockit injection also has three objects

  1. Objects created by static methods can only be injected through the constructor of the injected object, the set method, or by reflection
  2. If you annotate the mock object, you can use @injectMocks to decorate the injected object and automatically inject the mock object into the member variables of the injected object
  3. Mock objects created by @MockBean in Spring Boot will replace all objects of the same type in the Spring container, so no additional configuration is required as long as Spring Boot is automatically injected

Reflection injection

Spring Boot Test provides a convenient tool class ReflectionTestUtils, which has the setField() method, to mock a private member variable in a test object. Private variables can be injected

public class A{
	private B b;
}

B b = Mockit.mock(B.class);
A a = new A();
ReflectionTestUtils.setField(a, "b", b);
Copy the code

summary

Mockito is commonly used in Java world mock library, it’s a great convenience to test code coding, and then I will continue to introduce the Spring in the Boot Controller and Service layers test details, welcome to continue to pay attention.