In this particular case, I tried to test a servlet but I needed mock an inherited internal method getServletContext() , Thus spy(T) function creates a partial mock object, mixing mock and real functionality in the same object, this is an example how I used it.
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.nebulaobjects.services.ForwardServlet;
import com.nebulaobjects.services.TestBase;
public class TestForwardServlet extends TestBase {
protected ForwardServlet real, spy;
protected ServletContext ctx;
protected RequestDispatcher dispatcher;
protected HttpServletRequest request;
protected HttpServletResponse response;
protected ServletConfig conf;
public void setUp() {
real = new ForwardServlet();
spy = spy(real);
conf = mock(ServletConfig.class);
ctx = mock(ServletContext.class);
request = mock(HttpServletRequest.class);
response = mock(HttpServletResponse.class);
dispatcher = mock(RequestDispatcher.class);
when(ctx.getRequestDispatcher(anyString())).thenReturn(dispatcher);
doReturn(ctx).when(spy).getServletContext();
}
public void testForward() throws ServletException, IOException {
String version = "v1";
doReturn(version).when(spy).getInitParameter("version");
spy.init(conf);
when(request.getRequestURI()).thenReturn(
"/services/health/1/3/4/5/6/7/8/9/10/service");
spy.forward(request, response);
verify(ctx, times(1)).getRequestDispatcher(
"/services/" + version
+ "/health/1/3/4/5/6/7/8/9/10/service");
}
}