Mockito: How to mock protected method

Created on 2 Dec 2016  路  4Comments  路  Source: mockito/mockito

Hey,

I have a question for JUnit test. I need to test the InvoiceAction.class. But InvoiceAction extends Strus2Action and the getSession() is a protected method.
I did try very much, but have to modify the source code. As the unit tester, not power to modify the source code, so come here to ask for help.

public class InvoiceAction extends Struts2Action {
    public String demoMethod() {
        String userCode = (String) getSession().getAttribute("UserCode");
        return null;
    }
} 
public class Struts2Action extends ActionSupport {
    protected HttpServletRequest getRequest() {
        return ServletActionContext.getRequest();
    }

    protected ServletContext getServletContext() {
        return ServletActionContext.getServletContext();
    }

    protected HttpSession getSession() {
        return getRequest().getSession();
    }
}
question

Most helpful comment

In this case you can use spy (see Spying on real objects):

InvoiceAction action = Mockito.spy(new InvoiceAction());
// Stub out getSession() call
// NOTE: you need to use doReturn() here, because otherwise actual implementation of getSession() will be called if you attempt to use when(action.getSession())
doReturn(fakeSession).when(action).getSession();

action.demoMethod();

// Verify results etc.

All 4 comments

In this case you can use spy (see Spying on real objects):

InvoiceAction action = Mockito.spy(new InvoiceAction());
// Stub out getSession() call
// NOTE: you need to use doReturn() here, because otherwise actual implementation of getSession() will be called if you attempt to use when(action.getSession())
doReturn(fakeSession).when(action).getSession();

action.demoMethod();

// Verify results etc.

@vyazelenko
I tried your Suggestions, but still won't do. Display the error message: The method getsession() is undefined for the type InvoiceAction.
I have to change getSession() method of the type, from the protected to the public.

InvoiceAction action = Mockito.spy(new InvoiceAction());
//create session
HttpSession session=ServletActionContext.getRequest().getSession();
//  and the getSession() hava a red underline,not pass.
Mockito.doReturn(session).when(action).getSession();

@yujishe This a pure Java _issue_, protected method can only be seen by the subclass when in a different package. The only option you have is to write a getSession method in InvoiceAction

public class InvoiceAction extends Struts2Action {
    public String demoMethod() {
        String userCode = (String) getSession().getAttribute("UserCode");
        return null;
    }

    HttpSession getSession() {
        return super.getSession();
    }
} 

Then you can use @vyazelenko's answer.

Notice that I used no visibility modifier here to reduce the visibility of InvoiceAction.getSession to the current package.

Depending on how works Struts2Action there may be other way(s) to give a fake http session, however this probably won't involve mocks.

thank you,I solved the problem of this method.I suggested use refactoring to the superior.
public String findUserCodeFromSession() { String userCode = (String) getSession().getAttribute("UserCode"); return userCode; }

use a extract method for create the method ,that I can set a Stub for test the demoMethods();

Was this page helpful?
0 / 5 - 0 ratings