尝试使用 JUnit、Mockito 测试 Spring MVC 控制器方法时出现 NullPointerException
NullPointerException while trying to test a Spring MVC controller method with JUnit, Mockito
我正在尝试对 Spring MVC 控制器方法进行单元测试,但我的单元测试一直失败。
我有一个 Spring MVC 控制器方法:
// 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;
}
我正在尝试使用 JUnit 测试此控制器方法。我的单元测试经验很少,正在努力学习。如果没有模拟库,这似乎几乎不可能或没有意义,而且我正在处理的项目已经将 Mockito 作为依赖项,因此我正在尝试使用它。我的测试 class 如下:
//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);
}
}
当我 运行 我的测试时,它失败了,我在控制台中得到一个 java.lang.NullPointerException
异常,用空指针异常注释指定上面的行。
我已经尝试查找如何使用 Mockito 模拟 classes,并且我一直看到 @Mock
注释,我已经将其作为 @Mock DataUser
(以及其他 classes 我在我想我需要模拟的控制器方法中使用)。
我如何让它工作?似乎我必须用假数据创建一个全新的 DataUser
对象,但这似乎违背了模拟库的目的。如果我必须用假数据创建自己的对象,那么使用 Mockito 有什么意义呢?或者,我可能因为缺乏经验而误解了这一点。
请记住,默认情况下,unstubbed 方法 return 调用时 return 类型的默认值(数字为 0,对象为 null)。
你还没有存根 request.getSession()
所以它 return 是空的。
您需要:
- 为会话提供模拟
- 将
request.getSession()
存根到 return 这个模拟
- 存根
session.getAttribute("currentUser")
最重要的是:
虽然在测试中调用控制器方法当然具有测试方法主体的价值,但如果将测试重新实现为 @WebMvcTest[,您将测试更多功能(如请求和响应序列化) =14=]
我正在尝试对 Spring MVC 控制器方法进行单元测试,但我的单元测试一直失败。
我有一个 Spring MVC 控制器方法:
// 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;
}
我正在尝试使用 JUnit 测试此控制器方法。我的单元测试经验很少,正在努力学习。如果没有模拟库,这似乎几乎不可能或没有意义,而且我正在处理的项目已经将 Mockito 作为依赖项,因此我正在尝试使用它。我的测试 class 如下:
//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);
}
}
当我 运行 我的测试时,它失败了,我在控制台中得到一个 java.lang.NullPointerException
异常,用空指针异常注释指定上面的行。
我已经尝试查找如何使用 Mockito 模拟 classes,并且我一直看到 @Mock
注释,我已经将其作为 @Mock DataUser
(以及其他 classes 我在我想我需要模拟的控制器方法中使用)。
我如何让它工作?似乎我必须用假数据创建一个全新的 DataUser
对象,但这似乎违背了模拟库的目的。如果我必须用假数据创建自己的对象,那么使用 Mockito 有什么意义呢?或者,我可能因为缺乏经验而误解了这一点。
请记住,默认情况下,unstubbed 方法 return 调用时 return 类型的默认值(数字为 0,对象为 null)。
你还没有存根 request.getSession()
所以它 return 是空的。
您需要:
- 为会话提供模拟
- 将
request.getSession()
存根到 return 这个模拟 - 存根
session.getAttribute("currentUser")
最重要的是:
虽然在测试中调用控制器方法当然具有测试方法主体的价值,但如果将测试重新实现为 @WebMvcTest[,您将测试更多功能(如请求和响应序列化) =14=]