Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito TooManyActualInvocations

I'm using Junit and Mockito to test forward. Here is part of PortalServletTest class:

@SuppressWarnings("serial")
@BeforeClass
public static void setUpTests() {
    when(request.getRequestDispatcher(Mockito.anyString())).thenReturn(rd);
    when(request.getSession()).thenReturn(httpSession);
    when(httpSession.getServletContext()).thenReturn(servletContext);
    when(servletContext.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).thenReturn(configurationManager);
    when(configurationManager.getConfiguration()).thenReturn(configuration);
    List<List<String>> mandatoryHeaders = new ArrayList<List<String>>();
    mandatoryHeaders.add(new ArrayList<String>() {
        {
            add("HTTP_XXXX");
            add("http-xxxx");
        }
    });

    List<List<String>> optionalHeaders = new ArrayList<List<String>>();
    optionalHeaders.add(new ArrayList<String>() {
        {
            add("HTTP_YYYY");
            add("http-yyyy");
        }
    });

    when(configuration.getIdentificationHeaderFields()).thenReturn(mandatoryHeaders);
    when(configuration.getOptionalHeaderFields()).thenReturn(optionalHeaders);

}

@Test
public void testMissingHeadersRequest() throws IOException {
    when(request.getHeader(Mockito.anyString())).thenReturn(null);
    target().path("/portal").request().get();
    Mockito.verify(response, times(1)).sendError(HttpServletResponse.SC_USE_PROXY, PortalServlet.MISSING_HEADERS_MSG);
}

@Test
public void testSuccesfulRequest() throws IOException, ServletException {
    Mockito.doAnswer(new Answer<Object>() {
        public Object answer(InvocationOnMock invocation) {
            Object[] args = invocation.getArguments();
            String headerName = (String) args[0];
            return headerName;
        }
    }).when(request).getHeader(Mockito.anyString());
    target().path("/portal").request().get();
    verify(rd).forward(Mockito.any(ServletRequest.class), Mockito.any(ServletResponse.class));
}

The PortalServlet code:

RequestDispatcher rd = request.getRequestDispatcher("index.html");
        rd.forward(mutableRequest, response);

The problem is that when testing the class, I'm getting the error message:

requestDispatcher.forward(, ); Wanted 1 time: -> at xxx.PortalServletTest.testSuccesfulRequest(PortalServletTest.java:140)

But was 2 times. Undesired invocation: -> at xxx.PortalServlet.addRequestHeaders(PortalServlet.java:144)

at xxx.PortalServletTest.testSuccesfulRequest(PortalServletTest.java:140)

If I run each test individually they pass OK. Looks like the forward from PortalServlet is count twice for each test. Any suggestion how to solve this issue?

Thanks in advance.

like image 882
Israel Avatar asked Mar 10 '23 05:03

Israel


2 Answers

In addition to what @GhostCat wrote, I think you should reset all mocked objects before tests:

@Before
public void before() {
   Mockito.reset(/*mocked objects to reset*/)
   // mock them here or in individual tests
}
like image 123
Enigo Avatar answered Mar 20 '23 23:03

Enigo


You are using @BeforeClass to configure your mock objects.

That method is called once before your @Tests in your test class go executed.

You could simply try to change that to @Before!

In other words: before doing any tests, you configure your mocks to allow for one call. But then you are running multiple tests. If you assume that your mocks are all used the same way, you simply re-configure them each time for each @Test method.

Given your comment: does this

verify(rd, times(2)).forward ...

work/help?

like image 21
GhostCat Avatar answered Mar 21 '23 00:03

GhostCat