If we only need to mock several methods of a class leaving the rest free to respond to calls normally, we cannot mock it, we have to spy it. Here is an example:

Class to be tested










public class MyClass extends MyBaseClass {
    public void myMethod(Product p) {
        p.setDescription("desc");
        save(p);
    }
    public void save(Product p) {
        super.save(p);
    }
If we want to test myMethod, but mock the save method:


















@Spy
@InjectMocks
private MyClass myClass;
@Test
public void testMyMethod() {
    // Preparation
    Product p = new Product();
    doNothing().when(myClass).save(p);
    // Run Test
    myClass.myMethod(p);
    // Control
    assertEquals("desc", p.getDescription());
    verify(myClass).save(p);
}
Here if we used @Mock instead of @Spy, we would see this error:
This combination of annotations is not permitted on a single field:
@Mock and @InjectMocks
as we cannot say “I want to mock myClass” and “I also want to test myClass, therefore inject my mocks into it” at the same time.
Code Coverage shows us which lines were executed:
Screen Shot 2015-02-13 at 19.34.44
If our method was not a void one, we would use doReturn() instead of doNothing(), rest remains the same.

public Product save(Product p) {
    return super.save(p);
}

@Test
public void testMyMethod() {
    // Preparation
    Product p = new Product();
    doReturn(null).when(myClass).save(p);
}


@Test
public void testMyMethod() {
    // Preparation
    Product p = new Product();
    doReturn(null).when(myClass).save(p);
            ...
We could have prepared another product instance with an id, and let the save return that instead of null as hibernate would do; but you get the idea anyway.

Note: As i just wanted to show you how to use @Spy, i intentionally did not evaluate all method results properly, as i would normally do like in this post.
Then my test would look like this:


























@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
    @Spy
    @InjectMocks
    private MyClass myClass;
    @Mock
    private Product productMock;
    @Test
    public void testMyMethod() {
        // Preparation
        doNothing().when(myClass).save(productMock);
        // Run Test
        myClass.myMethod(productMock);
        // Control
        InOrder inOrder = Mockito.inOrder(productMock, myClass);
        inOrder.verify(productMock).setDescription("desc");
        verifyNoMoreInteractions(productMock);
        inOrder.verify(myClass).save(productMock);
    }
}
Note 2: I will write a separate post about how to mock super class calls, since it is not readily possible with Mockito.