Mockito:参数的模拟服务抛出空指针异常

时间:2018-03-05 23:38:35

标签: junit mockito

使用此控制器方法进行测试

@RequestMapping("/search/{q}")
public String getWeatherForSearchTerm(@PathVariable String q, Model model) {
    GeocodingResult geocodingResult = geocodingService.findBySearchTerm(q);
    Weather weather = weatherService.findByLocation(geocodingResult.getGeometry().getLocation());
    model.addAttribute("geocodingResult",geocodingResult);
    model.addAttribute("weather",weather);
    return "weather/detail";
}

尝试运行此测试

@Test
public void getWeatherForSearchTermTest() throws Exception{
    GeocodingResult geocodingResult = new GeocodingResult();

    Weather weather = new Weather();

    Mockito.when(geocodingService.findBySearchTerm("13")).thenReturn(geocodingResult);

    Mockito.when(weatherService.findByLocation(any(Location.class))).thenReturn(weather);
    mockMvc.perform(get("/search/13"))
            .andExpect(MockMvcResultMatchers.view()
            .name("weather/detail"));
    Mockito.verify(geocodingService).findBySearchTerm(any(String.class));
}

我在尝试在Controller中执行此代码行时收到NullPointerException

Weather weather = weatherService.findByLocation(geocodingResult.getGeometry().getLocation());

即使

        Mockito.when(weatherService.findByLocation(any(Location.class))).thenReturn(weather);

已定义。

经过调试后,我意识到这是抛出异常的部分。

    geocodingResult.getGeometry().getLocation()

我不明白为什么如果我在代码片段代码中模拟了如上所示的响应,就会发生这种情况。

我的课程用

注释
@RunWith(MockitoJUnitRunner.class)

并定义了memeber类:

 private MockMvc mockMvc;

@InjectMocks
private WeatherController controller;

@Mock
private WeatherService weatherService;

@Mock
private GeocodingService geocodingService;

1 个答案:

答案 0 :(得分:0)

嘲笑没有错。问题是,您正在返回GeocodingResult的浅层对象。 GeocodingResult的基础属性(例如geometry)未明确设置,因此它们必须已初始化为null。

您需要执行类似

的操作
@Test
public void getWeatherForSearchTermTest() throws Exception {
    Geometry geometry = new Geometry();
    // Assuming location is string
    geometry.setLocation("Mars");

    GeocodingResult geocodingResult = new GeocodingResult();
    geocodingResult.setGeometry(geometry);
    // remaining code here
}