2.1 @Mock annotation

There are two ways to work with mock objects in Mockito. The first is to create a fully virtual object , the second is to wrap an existing object in a wrapper. Let's start with the first one.

To create a fully virtual object, you need to write the code:

ClassName variable name = Mockito.mock(ClassName.class);

Let's create a mock ArrayList class as an example:

@ExtendWith(MockitoExtension.class)
class MockTest {
    @Test
    public void whenNotUseMockAnnotation_thenCorrect() {
        List mockList = Mockito.mock(ArrayList.class);
        //these methods won't do anything - they are stubs
        mockList.add("one");
        mockList.add("two");
    }
}

In this example, we create a fake ArrayList and store a reference to it in the mockList variable. The methods of this object do nothing.

By the way, this code can be written even shorter, since there is a special annotation for this @Mock.

@ExtendWith(MockitoExtension.class)
class MockTest {
    @Mock
    List mockList;

    @Test
    public void whenNotUseMockAnnotation_thenCorrect() {
        //these methods won't do anything - they are stubs
        mockList.add("one");
        mockList.add("two");
    }
}

In the second case, MockitoExtensionit will analyze the class code itself and create the necessary stubs. You don't need to call the method Mockito.mock(). One annotation and the virtual object is ready. Beauty.

2.2 @Spy annotation

The second important type of objects in Mockito are wrappers over existing objects. They allow, on the one hand, to use existing classes, and on the other hand, to intercept calls to all methods and variables of such objects: to correct their work where necessary. They are used just as often as Mock objects.

To create a wrapper over an object, you need to write the code:

ClassName variable name = Mockito.spy(an object);

An example with a wrapper around the ArrayList class:

@ExtendWith(MockitoExtension.class)
class SpyTest {
    @Test
    public void whenMockAnnotation() {
        List<String> mockList = Mockito.spy(new ArrayList<String>());
        //these methods will work!
        mockList.add("one");
        mockList.add("two");
    }
}

In its simplest form, a call to a wrapper object simply redirects calls to the original object, the reference to which it keeps inside itself . Everything will work just like with the original object.

You can also create a wrapper using the annotation - @Spy.

@ExtendWith(MockitoExtension.class)
class SpyTest {
    @Spy
    List mockList = new ArrayList<String>();

    @Test
    public void whenMockAnnotation() {
        // these methods will work!
        mockList.add("one");
        mockList.add("two");
    }
}

These two code examples are equivalent.