简体   繁体   中英

NullPointerException while trying to test a Spring MVC controller method with JUnit, Mockito

I am trying to unit test a Spring MVC controller method, but my unit test keeps failing.

I have a Spring MVC controller method:

// MyController.java
@RequestMapping(value = "/end-point", method = RequestMethod.GET)
public ModelAndView getData(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    ModelAndView mv = new ModelAndView();
    DataManager dataManager = DataManager.getInstance();
    DataUser currentUser = (DataUser) request.getSession().getAttribute("currentUser");
    List<DataItem> dataList = dataManager.getDataForUser(currentUser.getId());
    mv.addObject("dataList", dataList);
    mv.setViewName("home-page");
    return mv;
}

I am trying to test this controller method with JUnit. I have very little experience unit testing and am trying to learn. Seems like this is near-impossible or does not make sense to do without a mocking library, and the project I'm working on already has Mockito as a dependency so I'm trying to use that. My test class is below:

//MyControllerTest.java
public class MyControllerTest {
    @InjectMocks
    private MyController myController;

    @Mock
    HttpServletRequest request;

    @Mock
    HttpServletResponse response;

    @Mock
    ModelAndView mockModelAndView;

    @Mock
    DataManager mockDataManager;

    @Mock
    DataUser mockDataUser;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getDataTest() throws Exception {
        //I guess I have to somehow mock mockDataUser here even more than @Mock???
        Mockito.when(request.getSession().getAttribute("currentUser")).thenReturn(mockVendorUser); // <-- this is where the null pointer exception is coming from
        Mockito.when(myController.getData(request, response)).thenReturn(mockModelAndView); 
        ModelAndView testing = profileControllerWH.getMySkus(request, response);
        assertEquals(1, 1);
    }
}

When I run my test, it fails and I get a java.lang.NullPointerException exception in the console, specifying the line above with the null pointer exception comment.

I have tried looking up how to mock classes with Mockito, and I keep seeing the @Mock annotation, which I already have as @Mock DataUser (as well as other classes I am using in the controller method that I guess I need to mock).

How do I get this to work? It seems like I have to create a whole new DataUser object with fake data, but then that seems to defeat the purpose of the mocking library. What would the point of using Mockito be if I have to create my own objects with fake data? Or, I might be misunderstanding this because of lack of experience.

Remember that by default, unstubbed methods return default value of return type when called (0 for numbers, null for Objects).

You haven't stubbed request.getSession() so it returns null.

You need to:

  • provide a mock for session
  • stub request.getSession() to return this mock
  • stub session.getAttribute("currentUser")

On top of that:

While calling the controller method in your test certainly has value of testing the method body, but you will test more functionality (like request and response serialization) if you re-implement your test as a @WebMvcTest

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM